【问题标题】:SQL Query: Update FromSQL 查询:更新自
【发布时间】:2013-11-25 10:18:36
【问题描述】:

这是正确的 SQL:

UPDATE T1alias
SET T1alias.Row2 = T2alias.Row2
FROM 
(
   T1 AS T1alias
   INNER JOIN 
   T2 AS T2alias
   ON T1alias.Row1 = T2alias.Row1
)

这个查询似乎返回了正确的结果,但我不明白为什么。 我的意思是 FROM 子句指的是一个完全不同的数据集,因为表 T1 必须更新。 F.e.:

 T1                                 T2
----------------------             ----------------------
| Row1 | Row2 | Row3 |             | Row1 | Row2 | Row3 |  
----------------------             ----------------------
| 1    | 2    | 3    |             | 1    | 7    | 8    |  
---------------------              ----------------------
| 4    | 5    | 6    |             | 9    | 10   | 11   |  
----------------------              ----------------------
 T1 INNER JOIN T2 ON T1alias.Row1 = T2alias.Row1
-------------------------------------------------------------
| T1.Row1 | T1.Row2 | T1.Row3 | T2.Row1 | T2.Row2 | T2.Row3 |  
-------------------------------------------------------------
| 1       | 2       | 3       |  1      | 7       | 8       |  
-------------------------------------------------------------

那么如何从连接的表中更新 T1?

在我看来,这些是完全不同的数据集。 如果它看起来像,我会理解 sql 查询:

UPDATE T1alias
SET T1alias.Row2 = T2alias.Row2
FROM 
(
   T1 AS T1alias
   INNER JOIN 
   T2 AS T2alias
   ON T1alias.Row1 = T2alias.Row1
) AS T1T2JoinedAlias
WHERE T1T2JoinedAlias.Row1 = T1alias.Row1

请有人向我解释一下。 (我正在使用 Microsoft SQL Server 2008 R2)

【问题讨论】:

  • 您的最后一个查询是错误的。更新查询中的表连接不能有别名。
  • @Fabian 如果您的意思是评论“这通过使用 UPDATE 迭代 INNER JOIN 来工作。因此 ON 函数作为您的 WHERE 子句和 INNER JOIN 跳过在 JOINed 中找不到的记录桌子。”但如果有人能更详细地解释一下,我会很高兴。
  • @user1911091 链接的问题和答案(特别是第一个答案)讨论了几种基于该表与另一个表的连接来更新单个表的方法。我知道这就是您要找的东西?
  • 我更感兴趣的是它为什么以及如何工作。我知道语法(从我的问题中可以看出)。但我不明白为什么这个查询给出了正确的结果。因为 where 子句中的连接表是与 T1 完全不同的数据集,它已更新。 SQL Server 2008 如何处理连接。它如何知道要更新 T1 的哪些行。因为我没有定义规则。

标签: sql sql-server-2008 sql-update


【解决方案1】:

如果你看一下你的 SQL 语句的执行计划,你就会明白发生了什么:

如您所见(在我的例子中),查询优化器会扫描 FROM 子句中指定的两个表并检索满足内部连接的行。

这些行然后沿着链传递给 Table Update 物理运算符,如您所见,它被告知在 T1 上执行更新(您可以通过在上面的查询中说“Update T1Alias”来告诉它执行此操作,您还可以通过 SET 命令告诉它要更新哪些字段)

查询分析器倾向于在algebrizer将查询编译成二进制后为您的查询选择最佳执行计划,因此您是否获得与我相同的执行计划将取决于许多因素,包括您是否有索引表格。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多