使用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