在SQL中查找作为其他组的子集的组

时间:2017-06-27 21:14:36

标签: sql sql-server

我有一个如下表格,其中包含一组Groups,其中包含唯一的(在其内部)Values。我想知道哪些组是其他组的完整子集。当然,群体不应被视为自己的子集。

grouptable将:

ID | Group | Value
==================
00 |  A    |   1
01 |  A    |   2
02 |  A    |   3
03 |  B    |   1
04 |  B    |   3
05 |  C    |   7
06 |  D    |   2

我想要的内容(Smaller群组中的每个元素都包含在Bigger群组中):

Smaller | Bigger
================
  B     |    A
  D     |    A

我尝试了一些不同的查询,但我无法理解如何要求Bigger组中的每个元素都在{ {1}}小组。

我能做的最好的就是这个,它应该找到在另一个组中包含任何匹配Samller的组。如何将任何转换为 all

Value

3 个答案:

答案 0 :(得分:1)

假设您没有重复值(正如您的问题所指定的那样),那么您非常接近。您基本上需要left joinhaving子句:

select gt.group as smaller_group, gr2.group as bigger_group
from grouptable gt left join
     grouptable gt2
     on gt2.value = gt.value and
        gt2.group <> gt.group
group by gt.group, gr2.group
having count(*) = count(gt2.group);

having子句表示给定组的值数与第二组中的数字匹配。

答案 1 :(得分:1)

假设每个组和值没有重复项,您可以尝试:

SELECT G1.[Group] as smaller, G2.[Group] AS bigger FROM 
(SELECT [Group], count(*) AS Num FROM  GroupTable GROUP BY [Group]) G1 
INNER JOIN 
( SELECT A1.[Group], A2.[Group] as SmallGroup, count(*) AS Num2 
    FROM GroupTable A1  INNER JOIN  GroupTable A2 ON
    A1.[Value] = A2.[Value] 
    WHERE A1.[Group] <> A2.[Group]
    GROUP BY A1.[Group], A2.[Group] ) G2
    ON G1.[Group] = G2.SmallGroup 
    WHERE Num2 = Num

答案 2 :(得分:1)

下面的SQL示例首先将[Group]加入到具有相同[Value]&的其他人。

与Sergio Prats的答案类似,当联合[Group]的总唯一值与[Group]总共具有的总唯一值相同时,则将其保持为[Smaller]。

总计的CTE用于在连接中重复使用。

top 1 with ties仅用于保留最大[Bigger]

declare @GroupTable table (ID int identity(1,1), [Group] char(1), Value int);

insert into @GroupTable ([Group], Value) values
('A',1),('A',2),('A',3),('B',1),('B',3),('C',7),('D',2),('E',3);

;with CTE as
(
    select [Group], count(distinct [Value]) as Total 
    from @GroupTable
    group by [Group]
)
select top 1 with ties 
Q1.Group1 as [Smaller], 
Q1.Group2 as [Bigger]
from 
(
    select 
    t1.[Group] as Group1, 
    t2.[Group] as Group2, 
    count(distinct t1.Value) as Total1
    from @GroupTable t1
    join @GroupTable t2 ON (t1.Value = t2.Value AND t1.[Group] != t2.[Group])
    group by t1.[Group], t2.[Group]
) Q1
join CTE c1 on (Q1.Group1 = c1.[Group] and Q1.Total1 = c1.Total)
left join CTE c2 on (Q1.Group2 = c2.[Group])
order by c2.Total desc, Q1.Group2;

返回:

Smaller Bigger
B       A
D       A
E       A