基于子集

问题描述:

选择行我有一个场景,我需要编写SQL查询基于其他查询的结果。基于子集

考虑表中的数据:

id attribute 
1 a 
1 b 
2 a 
3 a 
3 b 
3 c 

我想写查询选择在属性设置ID基地。 我的意思是首先我需要使用此查询来检查ID 1的属性:

select attribute from table where id = 1 

那么这个结果,我需要选择属性的子集的基础。就像我们的情况1(a,b)是3(a,b,c)的子集。在这种情况下,我的查询应该返回3。

如果我想在检查基座2的(a),这是图1(a,b)和3(A,B,C),则它应该返回1和3

希望所述子集,这是可以理解的。 :)

+0

何不:'ID = 1返回1,3'并且'id = 2返回1,2,3''。您需要排除用于获取要与之比较的ID的ID吗? –

+0

这是不是一个问题是否返回i​​d = 1。我可以过滤它,但我主要关心的是获取基于属性的子集的ids。 – Saadi

您可以使用此查询。 逻辑很简单:如果没有任何项所述的并且不是在乙 - > A是B.

的子集
DECLARE @SampleData AS TABLE 
(
    Id int, attribute varchar(5) 
) 

INSERT INTO @SampleData 
VALUES (1,'a'), (1,'b'), 
(2,'a'), 
(3,'a'),(3,'b'),(3,'c') 

DECLARE @FilterId int = 1 

;WITH temp AS 
(
    SELECT DISTINCT sd.Id FROM @SampleData sd 
) 
SELECT * FROM temp t 
WHERE t.Id <> @FilterId 
AND NOT EXISTS (
      SELECT sd2.attribute FROM @SampleData sd2 
      WHERE sd2.Id = @FilterId 
      AND NOT EXISTS (SELECT * FROM @SampleData sd WHERE sd.Id = t.Id AND sd.attribute = sd2.attribute)   
     ) 

演示链接:Rextester

+0

'; WITH temp的用途AS ( SELECT DISTINCT sd.Id FROM @SampleData sd )'?这里使用CTE没有意义吗? –

+0

使用可以直接使用'@ SampleData'而不是'temp',最后是'Distinct'。这并没有什么不同。但是,例如,如果'Id = 1'具有1000个属性,那么您就调用1000次NOT EXIST ... for Id = 1. – TriV

+0

好的,我明白了。它在第一次表扫描后移动最终结果集的DISTICT SORT。 –

我会组成为一个查询的三个步骤:首先我会得到想要的id的属性,这是你写的

select attribute from table where id = 1 

然后我会得到的数查询属性所需的id

select count(distinct attribute) from table where id = 1 

最后,我想用上面的结果过滤

select id 
from table 
where id <> 1 and 
     attribute in (
      select attribute from table where id = 1 /* Step 1 */ 
     ) 
group by id 
having count(distinct attribute) = (
      select count(distinct attribute) from table where id = 1 /* Step 2 */ 
     ) 

这将使您获得所有id's,其中最初提供的id的数量等于最初的id所具有的数量中的attributes

+1

我更希望count(distinct属性)为'count(*)'。 –

+0

@VojtěchDohnal你说得对,谢谢。我改进了我的回答 –