【问题标题】:How does t-sql update work without a joint-sql 更新如何在没有连接的情况下工作
【发布时间】:2013-05-26 07:00:16
【问题描述】:

我觉得我的头是泥泞的什么的。我试图弄清楚从另一个表更新一个表时 t-sql 更新如何在没有连接的情况下工作。我过去一直使用连接,但遇到了一个存储过程,其他人在没有连接的情况下创建了一个。此更新正在 SQL 2008R2 中使用,并且可以正常工作。

Update table1

SET col1 = (SELECT TOP 1 colX FROM table2 WHERE colZ = colY),

col2 = (SELECT TOP 1 colE FROM table2 WHERE colZ = colY)

显然,colY 是 table1 中的一个字段。要在 select 语句(而不是更新)中获得相同的结果,需要连接。我想我不明白更新是如何在幕后工作的,但它一定是在做某种加入?

【问题讨论】:

  • “要在 select 语句中获得相同的结果,需要连接” - 不,correlated subqueriesSELECTs 中也可以正常工作
  • @AakashM - 我只使用了连接,所以没有尝试使用相关子查询进行选择。谢谢指正,我去看看

标签: sql-server tsql join


【解决方案1】:

SQL Server 将这些子查询转换为连接。您可以通过获取查询计划来查看这一点。您可以使用UPDATE ... FROM ... JOIN 语法编写等效查询,并观察查询计划基本相同。

显示的示例代码不寻常、难以理解、冗余且不灵活。我建议不要使用这种风格。

【讨论】:

  • 实际上由于 TOP 1 的原因,仅使用普通连接会有些困难。当然,除非 TOP 1 是多余的,而且这是保证的 1:1 关系。因为 OP 从同一个表中提取 2 列,所以我可能会使用 CTE 和 JOIN,但相关子查询的理论和使用通常是完全合理的。
  • 我的意思是“物理连接”,而不是代数连接。 SQL Server 可以使用嵌套循环连接运算符很好地处理相关连接。您必须在此特定查询中使用交叉应用。子查询总是被转换为 SQL Server 中的连接(或优化)。
【解决方案2】:

不,它正在执行子查询,在这种情况下是两个。如果你还有 98 个 col 字段,那就太痛苦了。

你可以为选择做类似的事情

select *,
(SELECT TOP 1 colX FROM table2 WHERE colZ = colY) as col1
From table1

左连接会更有效

您的示例,除非 dbms 对其进行优化,否则它会为表中的每一行运行子查询。 不得不说写它的人不够称职。

【讨论】:

    【解决方案3】:

    这些子查询就是所谓的相关子查询。如果您要编写与SELECT 而不是UPDATE 相同的查询,它将如下所示。

    SELECT col1 = (SELECT TOP 1 table2.colX FROM table2 WHERE table2.colZ = table1.colY),
        col2 = (SELECT TOP 1 table2.colE FROM table2 WHERE table2.colZ = table1.colY)
    FROM table1
    

    JOIN 是因为您从子查询内部的外部表中引用列。 Table1UPDATE 命令中被引用。您可以包含 FROM 子句,但这样的设置不需要它。

    【讨论】:

    • 哇,谢谢大家的建议。我要在这个网站上学到很多东西
    【解决方案4】:

    您可以在没有连接的 SELECT 中使用相同的语法,但如果 colY 也存在于 table2 中,则需要为表命名

    SELECT (SELECT TOP 1 colX FROM table2 WHERE colZ = T.colY)
    , (SELECT TOP 1 colE FROM table2 WHERE colZ = T.colY)
    FROM table1 AS T
    

    我只在为我自己的信息构建临时查询时使用这种东西。如果要将其放入任何类型的永久代码中,我会将其转换为联接,因为它更易于阅读且更易于维护。

    【讨论】:

    • 实际上不需要表别名,这只是一个好主意,因为它有助于使查询更具可读性。另一方面,如果coly 存在于内部和外部查询中,那么您需要包含表别名才能在外部查询中引用该版本。
    • 我的立场是正确的。在我的辩护中,我几乎总是使用别名来提高可读性,并且大多数情况下,我使用自联接这样的查询,因此需要别名
    • 一个很好的习惯,我希望我的所有开发人员都拥有!
    猜你喜欢
    • 2018-01-31
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 2022-10-26
    • 2012-06-11
    • 2012-02-10
    相关资源
    最近更新 更多