做了一個如下的小廁所,如果我需要得到返回是 d,f 那我需要用那組語句呢? A: B: C: 實際情況執行一下就知道,其實BC 的語句都可以執行。而A的執行情況就是只返回了 d。這個其實是跟select 的執行順序有關的。 通常我們看select 的執行順序的時候,可能會忽略這2個不常用的連接謂詞導 ...
做了一個如下的小廁所,如果我需要得到返回是 d,f 那我需要用那組語句呢?
A:
;WITH CA AS( SELECT * FROM (VALUES('a'),('b'),('c'),('d'))a (A)) ,CB AS ( SELECT * FROM (VALUES('a'),('b'),('c'),('f'))a (A) ) SELECT * FROM CA EXCEPT SELECT * FROM CB UNION SELECT * FROM CB EXCEPT SELECT * FROM CA
B:
;WITH CA AS( SELECT * FROM (VALUES('a'),('b'),('c'),('d'))a (A)) ,CB AS ( SELECT * FROM (VALUES('a'),('b'),('c'),('f'))a (A) ) SELECT * FROM CA EXCEPT SELECT * FROM CB UNION (SELECT * FROM CB EXCEPT SELECT * FROM CA)
C:
;WITH CA AS( SELECT * FROM (VALUES('a'),('b'),('c'),('d'))a (A)) ,CB AS ( SELECT * FROM (VALUES('a'),('b'),('c'),('f'))a (A) ) (SELECT * FROM CA EXCEPT SELECT * FROM CB) UNION (SELECT * FROM CB EXCEPT SELECT * FROM CA)
實際情況執行一下就知道,其實BC 的語句都可以執行。而A的執行情況就是只返回了 d。這個其實是跟select 的執行順序有關的。
通常我們看select 的執行順序的時候,可能會忽略這2個不常用的連接謂詞導致誤判。這裡做一個實驗就可以發現,其實 Except(Intersect 同理) 的查詢優先順序是和 union 或者union all 是同級的。
所以遵循從左到右的順序,如果不用括弧改變執行順序,從上面的例子,將會返回 CA Except CB -> Union CB -> Except CA 的執行結果。也就是一個容易忽略的位置。
因為比較少用,所以我也躺槍了。在此分享一波,希望大家不要踩坑。
PS
1 select 執行順序的地址 :https://docs.microsoft.com/zh-cn/sql/t-sql/queries/select-transact-sql
2 Except 和 Intersect 都是返回交叉之後不重覆的結果的,這個需要特別註意