2017-06-27 18 views
1

我有一個類似下面的表,其中包含一組Groups,它們包含唯一(在其內部)Values。我想知道哪些組是其他組的完整子集。當然,小組不應該被視爲自己的子集。在SQL中查找其他組的子集的組

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組中的每個元素都包含在Samller組中。

我已經能夠做的最好的是這個,它應該在另一個組中找到包含任意匹配Value的組。我如何將任何變成全部

-- Groups where G1 ⊆ G2 
SELECT G1.Group, G2.Group 
FROM GroupTable G1 
JOIN GroupTable G2 ON G2.Group <> G1.Group 
WHERE G1.Value = G2.Value 
GROUP BY G1.Group, G2.Group; 

回答

1

低於第一的SQL例如加入[集團]的給別人用相同的[值]的。

與Sergio Prats的回答類似,當加入的[Group]的總唯一值與[Group]總共的唯一值相同時,則將其保持爲[更小]。

具有總計的CTE用於在連接中重複使用。

而且top 1 with ties用於只保留最大[更大]

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 
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

假設每個集團和值沒有重複,你可以試試這個:

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 
相關問題