是否有人知道如何找到包含所有其他集合的集合
表
id elem 1 A 1 C 2 B 2 D 2 A 2 C 3 A 3 E 3 F 4 F 4 F
我想得到这个:
id 2 3
在这种情况下, id 2 包含(A,C) - 所有 id 1 的设置 并且 id 3 包含(F) - 所有 id 4
的设置在我的查询中,我需要获取包含所有set(所有元素)的所有id至少一个id 我将非常感激。谢谢。
答案 0 :(得分:1)
我没有太多关于这个,但它很感兴趣,所以我猜。我使用的是SQL Server
我提交了嵌套选择的答案,然后我按照一步一步的逻辑来说明发生了什么:
建立快速表格
CREATE TABLE a (id int, t varchar(10))
INSERT INTO a (id, t)
VALUES (1,'A'),(1,'B'),(1,'B'),(1,'B'),(2,'A')
,(2,'B'),(2,'C'),(3,'C'),(3,'D'),(4,'A'),(5,'P');
以下是解决方案:
select distinct p_id supersets from
(
select e.p_id, e.c_id, count(*) matches from (
select distinct c.id p_id, c.t p_t, d.id c_id, d.t c_t from a c
inner join a d on c.t = d.t and c.id <> d.id) e
group by e.p_id, e.c_id) sup
inner join
(select id, count(distinct t) reqs from a group by id) sub
on sub.id = sup.c_id and sup.matches = sub.reqs;
以下是帮助解释我为什么做我正在做的事情的逻辑步骤:
--Step1
--Create a list of matches between (distinct) values where IDs are not the same
select distinct c.id p_id, c.t p_t, d.id c_id, d.t c_t from a c
inner join a d on c.t = d.t and c.id <> d.id;
--Step2
--Create a unique list of parent IDs and their child IDs and the # of distinct matches
--For example 2 has 2 matches with 1 and vice versa
select e.p_id, e.c_id, count(*) matches from (
select distinct c.id p_id, c.t p_t, d.id c_id, d.t c_t from a c
inner join a d on c.t = d.t and c.id <> d.id) e
group by e.p_id, e.c_id;
--Step2a
--Create a sub query to see how many distinct values are in each "Set"
select id, count(distinct t) reqs from a group by id;
现在我们将它们全部放在连接中(上面,第一个),以确保从Parent到Child的匹配总数占子值的100%,即(是超集)
答案 1 :(得分:1)
我认为以下是您想要的:
select t1.id
from t t1 join
(select t.*, count(*) over (partition by id) as cnt
from t
) t2
on t1.elem = t2.elem and t1.id <> t2.id
group by t1.id, t2.id, t2.cnt
having count(*) = cnt;
这会根据元素将每个id与彼此的id匹配。如果匹配数等于第二组中的计数,那么所有匹配 - 你有一个超集。
我注意到你有重复的元素。让我们用CTE来处理这个问题:
with t as (
select distinct id, elem
from t
)
select t1.id
from t t1 join
(select t.*, count(*) over (partition by id) as cnt
from t
) t2
on t1.elem = t2.elem and t1.id <> t2.id
group by t1.id, t2.id, t2.cnt
having count(*) = cnt;