我有两个表Card
和History
具有一对多关系:一张卡可以具有一个或多个历史。Card
具有CardId
列,History
具有CardId
和StatusId
列。
我想要一个SQL脚本,该脚本选择唯一一个没有历史记录的卡片=310。
这就是我尝试的。
SELECT
C.CardId
FROM
Card C
WHERE NOT EXISTS (SELECT *
FROM History H
WHERE H.CardId = C.CardId AND H.StatusId = 310)
,但我想知道是否有有效的方法。
预先感谢。
回答有关是否有更有效方法的问题:
简短答案:不,not exists
很可能是最有效的方法。
长答案:亚伦·伯特兰(Aaron Bertrand)的文章具有基准测试,用于许多不同的方法,我是否应该不使用,外部应用,左外连接,除了或不存在吗?剧透:not exists
获胜。
我会坚持使用您的原始代码,但Aaron的文章有很多示例您可以适应您的情况,以确认没有其他任何东西更有效。
select c.CardId
from Card c
where not exists(
select 1
from History h
where h.CardId=c.CardId
and h.StatusId=310
)
所称为"负相关"。这是一个没有子查询的版本:
SELECT c.CardId
FROM Card c
LEFT OUTER JOIN History h
ON h.CardId = c.CardId
AND h.StatusId = 310
WHERE h.CardId IS NULL;
您的NOT EXISTS
方法看起来很合理,但是还有另一种方法。
SELECT *
FROM Card C
WHERE EXISTS (SELECT 1
FROM history H
WHERE H.CardId = C.CardId
HAVING Count(CASE WHEN H.StatusId = 310 THEN 1 END) = 0)
通过使用您的实时数据运行两个查询来检查性能