[英]return records that only match *all* of given IN values
有问题的表:
Persons
-------------------
PersonID (PK)
FirstName
LastName
Descriptors
-------------------
DescriptorID (PK)
Description
PersonDescriptors
-------------------
PersonID (PK)(FK)
DescriptorID (PK)(FK)
你好,
我有三个表:Persons,Descriptor和PersonDescriptors。 我试图找出一个查询:
接收可能的人员DescriptorID列表(例如:22、11、9等)
读取实际人员描述符记录的PersonDescriptors表(例如,行:PersonID:107,DescriptorID:22)
仅在所有提供的DescriptorID均匹配时才返回匹配的PersonID
例如,PersonID 107具有金色的头发(描述符ID:22),因此在PersonDescritors中具有107/22的一行。 PersonID 107也有胡须(DescriptorID:11),因此PersonDescriptors中的另一行是107/11。 如果我给查询提供这两个DescriptorID(22、11),它应该返回PersonID107。但是,如果我给查询22、11和9,它应该不返回PersonID 107,因为PersonDescriptor中没有107/9行。
PersonDescriptor中大约有一百万行。
您将如何编码?
一种想法是使用WHERE NOT EXISTS语句,但是我的尝试太慢了(在本地SQL Server 2014实例上超过20秒):
SELECT DISTINCT pd1.PersonID FROM PersonDescriptors pd1
WHERE NOT EXISTS (
SELECT 1 FROM PersonDescriptors pd2 WHERE NOT EXISTS (
SELECT 1 FROM PersonDescriptors pd3
WHERE
pd3.PersonID = pd1.PersonID
AND pd3.DescriptorID = pd2.DescriptorID
)
AND pd2.DescriptorID IN (1, 71) --two descriptors. more even slower
);
...另一种方法是采用目标DescriptorID的XML,并将它们加载到临时表中,每个DescriptorID一行,然后尝试一些JOIN魔术,但我无法弄清楚。
另一个想法是采用IN准则数量的HAVING COUNT,但是我也无法做到这一点。
我缺少想法,还是有帮助? 谢谢!
使用group by
并having
:
select pd.PersonId
from PersonDescriptors pd
where pd.DescriptorID IN (1, 71)
group by pd.PersonId
having count(distinct pd.DescriptorID) = 2;
您可以轻松地将此概括为任意长度的列表。 记住要更改having
子句中的常量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.