使用MSSQL Server 2008企业版,以及最有可能的其他版本的MSSQL,这里是一个概念证明,根据您使用JOIN或LEFT JOIN,使临时表和NEWID()具体化(即使我们匹配两排正好。为什么left join会导致NEWID()比join更早实现?
如果查看执行计划,可以看到使用JOIN最后执行的计算标量为NEWID(),但使用LEFT JOIN时不执行。我会期待LEFT JOIN的行为。这是由于执行计划中的天真或者有更多事情发生吗?
示范用临时表:
Create Table #Temp
(
ChildGuid uniqueidentifier,
ParentGuid uniqueidentifier
)
insert into #Temp (ChildGuid, ParentGuid) Values('5E3211E8-D382-4775-8F96-041BF419E70F', '96031FA0-829F-43A1-B5A6-108362A37701')
insert into #Temp (ChildGuid, ParentGuid) Values('FFFFFFFF-D382-4775-8F96-041BF419E70F', '96031FA0-829F-43A1-B5A6-108362A37701')
--Use a join. Get different NewIDs.
select * from #Temp
join
(
select ParentGuid, NewParentGuid from(
select ParentGuid, NEWID() as NewParentGuid from #Temp
group by ParentGuid
) tb2
) temp2 on #Temp.ParentGuid = temp2.ParentGuid
--Do exactly as above, but use a left join. Get a pair of the same NewIDs.
select * from #Temp
left join
(
select ParentGuid, NewParentGuid from(
select ParentGuid, NEWID() as NewParentGuid from #Temp
group by ParentGuid
) tb2
) temp2 on #Temp.ParentGuid = temp2.ParentGuid
随着加入,NewParentGuid是两行不同。
与左连接,NewParentGuid是相同的。
编辑2:如果将此附加到左连接,结果会更改。
where temp2.ParentGuid = temp2.ParentGuid
或者正如另一位用户指出的那样,该列不为空。他们在进行其他栏目的比较时或在1 = 1的情况下保持不变.Schroedinger的专栏?
参见:
Why does newid() materialize at the very end of a query?
之所以如此,是奇怪的,我本来期望的左连接导致这两种情况,因为你只有一个父母身份证。另一方面,如果你想单独使用newguids,则不需要任何代码。为什么不能:从#Temp – HLGEM 2014-09-25 18:07:12
中选择*,NEWID()作为NewParentGuid我也很惊讶地看到JOIN行为,而我期望它的行为像左连接,所以我更新了我的帖子以提及这一点。 – John 2014-09-25 18:41:41
一个是散列连接,另一个是合并连接,但如果强制它们都相同,结果是相同的。 – Paparazzi 2014-09-25 20:27:40