Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server t-sql更新在没有连接的情况下如何工作_Sql Server_Tsql_Join - Fatal编程技术网

Sql server t-sql更新在没有连接的情况下如何工作

Sql server t-sql更新在没有连接的情况下如何工作,sql-server,tsql,join,Sql Server,Tsql,Join,我觉得我的头有点泥泞什么的。我试图弄清楚在从一个表更新另一个表时,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 = c

我觉得我的头有点泥泞什么的。我试图弄清楚在从一个表更新另一个表时,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是表1中的一个字段。要在select语句(而不是update)中获得相同的结果,需要联接。我想我不明白更新在幕后是如何工作的,但它一定是在进行某种连接?

SQL Server将这些子查询转换为连接。您可以通过获取查询计划来了解这一点。您可以使用
UPDATE。。。从…起加入
语法,并观察基本相同的查询计划


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

您可以在没有联接的SELECT中使用相同的语法,但如果表2中也存在colY,则需要为该表添加别名

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

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

不,它正在执行子查询,在本例中是两个。如果你再有一次,那会很痛苦的

您可以为select执行类似的操作

select *,
(SELECT TOP 1 colX FROM table2 WHERE colZ = colY) as col1
From table1
左连接将更有效

除非dbms对其进行优化,否则将为表中的每一行运行子查询。
必须说,无论是谁写的,都不称职。

这些子查询就是所谓的相关子查询。如果要编写与
选择
而不是
更新
相同的查询,它将如下所示

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
实际上是从子查询内部的外部表中引用一列<代码>表1在
更新
命令中引用。您可以包含一个
FROM
子句,但这样的设置不需要它。

“要在select语句中获得相同的结果,需要一个联接”-不,在
select
s中可以正常工作too@AakashM-我只使用了连接,所以没有尝试使用相关子查询进行选择。感谢您纠正我的错误,我将检查它实际上表别名不是必需的,这只是一个好主意,因为它有助于使查询更具可读性。另一方面,如果
coly
同时存在于内部和外部查询中,那么您需要包括表别名,以便在外部查询中引用版本。我已更正。在我的辩护中,为了可读性,我几乎总是使用别名,大多数情况下,对于这样的查询,我使用的是自连接,因此别名需要养成良好的习惯,我希望我的所有开发人员都有这样的习惯!哇,谢谢大家的建议。我将在这个网站上学到很多东西,实际上,由于排名前1的原因,仅仅使用普通的连接有点困难。当然,除非前1是多余的,而且是保证的1:1关系。因为OP是从同一个表中提取两列,所以我可能使用CTE和联接,但是相关子查询的理论和使用通常是完全合理的。我的意思是“物理联接”,而不是代数联接。使用嵌套循环联接操作符,SQL Server可以很好地处理相关联接。在这个特定的查询中必须使用交叉应用程序。子查询总是在SQL Server中转换为联接(或优化)。
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