SQL 包含其他子集的集合问题

SQL Set containing other subsets question

假设您有一个值为 {x1, x2...xn} 的列 X。现在每个 x 包含一组值 {a1...an}。

例如:x1 链接到 {a1,a3},x2 链接到 {a3},x3 链接到 {a1, a2, a3}。

我需要创建一个查询,为每个 Xi 输出具有包含在 Xi 集合中的集合的其他 X 的数量,即它们包含 Xi 集合的子集。

这是此示例的示例输入 table:

.

这是预期的结果:

。如您所见,X1 仅包含 X2。 X2 不包含其他 x 的集合。 X3 包含 X1 和 X2

我不能使用任何程序扩展(所以不能使用 PLpgsql)或用户定义的函数。它必须纯粹是来自标准 SQL.

的查询

下面的查询可以做到这一点。 在您的记录集中,我添加了一个名为 (X4,A10) 的新行。如果您能找到其他解决方案,我很感兴趣

create table dbo.t(a varchar(10),b varchar(10))

insert into dbo.t values('X1','A1')
insert into dbo.t values('X1','A3')
insert into dbo.t values('X2','A3')
insert into dbo.t values('X3','A1')
insert into dbo.t values('X3','A2')
insert into dbo.t values('X3','A3')
insert into dbo.t values('X4','A10')

-- I have added comments
with cross_prod /*I am building the combination of elements of a with the values of other sets..*/
  as (
  select m.a main_a,n.a other_a,n.b other_b
    from (select distinct a 
            from dbo.t
         ) m
    join dbo.t n
      on m.a<>n.a  
      )
   ,interim_data
   as (
        select  q1.main_a
                ,q1.other_a
                /*Here full_match_flag=0 if all the elements match*/
                ,count(case when q2.main_a is null then 1 end) as full_match_flag 
          from cross_prod q1
        left join (/*This portion gets me the data where the elements match*/
                   select m.a as main_a,n.a as other_a,n.b as other_b
                     from dbo.t m
                     join dbo.t n
                       on m.a<>n.a  
                     where m.b=n.b
                    )q2
            on q1.main_a=q2.main_a
           and q1.other_a=q2.other_a
           and q1.other_b=q2.other_b
        group by q1.main_a
                ,q1.other_a   
       )
select main_a
       ,count(case when full_match_flag=0 then 1 end) as cnt_matches
 from interim_data
group by main_a

+--------+-------------+
| main_a | cnt_matches |
+--------+-------------+
| X1     |           1 |
| X2     |           0 |
| X3     |           2 |
| X4     |           0 |
+--------+-------------+