我想从一个匹配 ALL 指定值的表中提取结果,其中指定的值在另一个表中。我可以这样做:
SELECT * FROM Contacts
WHERE
EXISTS (SELECT 1 FROM dbo.ContactClassifications WHERE ContactID = Contacts.ID AND ClassificationID = '8C62E5DE-00FC-4994-8127-000B02E10DA5')
AND EXISTS (SELECT 1 FROM dbo.ContactClassifications WHERE ContactID = Contacts.ID AND ClassificationID = 'D2E90AA0-AC93-4406-AF93-0020009A34BA')
AND EXISTS etc...
然而,当我达到约40项EXISTS条款时,这种情况就会失败。错误消息是“查询处理器耗尽了内部资源,无法生成查询计划。这是一种罕见的事件,仅适用于引用大量表或分区的极其复杂的查询或查询。请简化查询。“
答案 0 :(得分:6)
这要点是
IN
声明DISTINCT COUNT
获取与GUID匹配的每个联系人的计数HAVING
仅保留那些与您在IN
语句中放入的匹配GUID数量相等的联系人SQL声明
SELECT *
FROM dbo.Contacts c
INNER JOIN (
SELECT c.ID
FROM dbo.Contacts c
INNER JOIN dbo.ContactClassifications cc ON c.ID = cc.ContactID
WHERE cc.ClassificationID IN ('..', '..', 38 other GUIDS)
GROUP BY
c.ID
HAVING COUNT(DISTINCT cc.ClassificationID) = 40
) cc ON cc.ID = c.ID
的测试脚本
答案 1 :(得分:3)
一种解决方案是要求在没有匹配联系人的情况下不存在分类。这是一个双重否定:
select *
from contacts c
where not exists
(
select *
from ContactClassifications cc
where not exists
(
select *
from ContactClassifications cc2
where cc2.ContactID = c.ID
and cc2.ClassificationID = cc.ClassificationID
)
)
此类问题称为relational division。
答案 2 :(得分:0)
SELECT c.*
FROM Contacts c
INNER JOIN
(cc.ContactID, COUNT(DISTINCT cc.ClassificationID) as num_class
FROM ContactClassifications
WHERE ClassificationID IN (....)
GROUP BY cc.ContactID
) b ON c.ID = b.ContactID
WHERE b.num_class = [number of distinct values - how many different values you put in "IN"]
如果您运行SQLServer 2005及更高版本,您可以使用CROSS APPLY
执行相同的操作,假设效率更高