我最近刚刚通过阅读同事编写的代码了解到 SQL Server 中存在新的“EXCEPT”子句(有点晚了,我知道......)。真的让我很惊讶!
但是我对它的使用有一些疑问:建议什么时候使用它?使用它与使用“AND NOT EXISTS...”的相关查询在性能方面有区别吗?
在阅读了 BOL 中的 EXCEPT 文章后,我认为这只是第二个选项的简写,但当我使用它重写了几个查询时感到惊讶(所以他们有我更熟悉的“AND NOT EXISTS”语法)然后检查执行计划——惊喜! EXCEPT 版本的执行计划更短,执行速度也更快。总是这样吗?
所以我想知道:使用这个强大工具的指南是什么?
EXCEPT
treats NULL
值作为匹配。
这个查询:
WITH q (value) AS
(
SELECT NULL
UNION ALL
SELECT 1
),
p (value) AS
(
SELECT NULL
UNION ALL
SELECT 2
)
SELECT *
FROM q
WHERE value NOT IN
(
SELECT value
FROM p
)
将返回一个空行集。
这个查询:
WITH q (value) AS
(
SELECT NULL
UNION ALL
SELECT 1
),
p (value) AS
(
SELECT NULL
UNION ALL
SELECT 2
)
SELECT *
FROM q
WHERE NOT EXISTS
(
SELECT NULL
FROM p
WHERE p.value = q.value
)
将返回
NULL
1
, 和这个:
WITH q (value) AS
(
SELECT NULL
UNION ALL
SELECT 1
),
p (value) AS
(
SELECT NULL
UNION ALL
SELECT 2
)
SELECT *
FROM q
EXCEPT
SELECT *
FROM p
将返回:
1
也允许递归引用EXCEPT
递归中的子句CTE
,尽管它的行为方式很奇怪:它返回除last row前一组的,不是除了整个前一组之外的所有内容:
WITH q (value) AS
(
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
),
rec (value) AS
(
SELECT value
FROM q
UNION ALL
SELECT *
FROM (
SELECT value
FROM q
EXCEPT
SELECT value
FROM rec
) q2
)
SELECT TOP 10 *
FROM rec
---
1
2
3
-- original set
1
2
-- everything except the last row of the previous set, that is 3
1
3
-- everything except the last row of the previous set, that is 2
1
2
-- everything except the last row of the previous set, that is 3, etc.
1
SQL Server
开发人员一定是忘记禁止它了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)