SQL Server 查找包含的组

4

我试图选择不包含在其他组中的组。

在这个例子中,组号为2的组被包含在组号为1的组中,因为组号为1拥有所有组号为2的值。

组号为3不包含在组号为1的组中,因为它有值50,而组号为1没有该值。

结果应该是组号为1和3的组。

(或者相反,只获取包含在其他组中的组,如组号为2)

寻找一种无需循环的方法,因为我的表格有超过200万个值。

我的表格长这样:

group_number    id
-------------------    
1               10
1               20
1               30
1               40
2               10
2               40
3               10
3               30
3               50
4个回答

5
我已经使用您提供的数据进行了测试,它可以正常工作。 第一个是不包含在另一个组中的组:
SELECT DISTINCT Group_Number FROM #T
    WHERE NOT EXISTS (SELECT Group_Number G2 
                    FROM #T AS T2 
                    WHERE T2.Group_Number <> #t.Group_Number
                      AND T2.ID = #T.ID)

另一种方法非常简单,只需使用以下代码:

SELECT DISTINCT Group_Number FROM #T WHERE NOT Group_Number IN (
  SELECT DISTINCT Group_Number FROM #T
    WHERE NOT EXISTS (SELECT Group_Number G2 
                    FROM #T AS T2 
                    WHERE T2.Group_Number <> #t.Group_Number
                      AND T2.ID = #T.ID)
  )

只是问自己,我意识到我的回答并不完全准确。 首先,我意识到添加以下内容:
INSERT INTO #t 
VALUES (6, 50),
    (7, 60),
    (8, 50),
    (8, 60)

第8组没有出现,因为其中一个项目在第6组中,另一个项目在第7组中。因此,我进行了大量检查并得出结论,以下代码可以保证结果,并提供可追溯性以验证响应是否正确:

SELECT DISTINCT Group_Number FROM 
    (
    SELECT T1.Group_Number, T1.Rows, T2.Group_Number as Comparing_With_Other_Group, Count(DISTINCT T2.ID) AS Rows_On_Other_Group
        FROM (
            SELECT Group_Number, Count(DISTINCT ID) AS Rows 
                FROM #T
                GROUP BY Group_Number
        ) T1
        INNER JOIN #T AS T2
            ON T1.Group_Number <> T2.Group_Number
            AND EXISTS (SELECT 1 FROM #T WHERE #T.Group_Number = T1.Group_Number and #T.ID = T2.ID)
        GROUP BY T1.Group_Number, T2.Group_Number, T1.Rows
    ) SubQry
    WHERE Rows = Rows_On_Other_Group

如果你只运行SubQry,你将看到可追溯性,而完整的查询将向你展示系统可以找到过滤所搜寻组的ID的另一个组的群组,在这个群组中,找到相同数量的ID。

2
您可以尝试以下查询。
SELECT DISTINCT Group_Number FROM #temp
    WHERE NOT EXISTS (SELECT DISTINCT Group_Number G2 
                    FROM #temp AS T2 
                    WHERE T2.Group_Number <> #temp.Group_Number
                      AND T2.ID = #temp.ID)

输出结果为-
Group_Number
1
3

Demo


2

我通过使用计数逻辑到达了你的逻辑。

   create table grp(a int ,b int)

   insert into grp

   select 1,10 union
   select 1,20 union
   select 1,30  union
   select 1,40  union
   select 2,10  union
   select 2,40  union
   select 3,10  union
   select 3,30  union
   select 3,50



   drop table #temo
   select distinct b.a as d ,b.b as g into #temo
   from grp a inner join grp b on (a.a<>b.a and a.b=b.b)
   where a.a <> b.a


   select a from grp
   except
   select a.d from (
   select d,count(tt) as cnt from (
   select d,g,row_number() over (partition by d  order by d)  tt from 
   #temo
   )rr
   group by d) a inner join (select a,count(a) as cnt from grp
   group by a) b on a.d=b.a and a.cnt=b.cnt

希望这有所帮助。

1
每个组号代表一个集合,您希望检查给定的集合是否是另一个集合的子集。您可以将表格与自身连接以将每个集合与所有其他集合匹配,并使用左连接+计数来确定 A 是否是 B 的子集(组 A 中的每一行都有相匹配的行在组 B 中):
SELECT a.group_number
FROM t AS a
INNER JOIN (
    SELECT DISTINCT group_number
    FROM t
) AS x ON x.group_number <> a.group_number
LEFT JOIN t AS b ON b.group_number = x.group_number AND b.id = a.id
GROUP BY a.group_number, x.group_number
HAVING COUNT(a.id) = COUNT(b.id)

上述返回的是另一个组的子集的组ID(在您的示例中为2)。将其用于NOT IN中,以获取非子集组ID。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接