SQL 找到所有同源类别

SQL find all homologous categories

我在类别和项目之间有一个多对多关系,它是用 "category_item" table 实现的,有 2 列(PK):category_iditem_id.

两个同源类别有相同的项目(顺序无关):

A
  1
  2

同源
B
  1
  2

但不是

C       D       E
  1       1       1
  3               2
                  3

给定类别 ID,如何找到所有同源类别?


假设这个数据在item_category:

A   1
A   2
B   1
B   2
C   1
C   3
D   1
E   1
E   2
E   3

我想找到与A同源的所有类别(预期结果只是B

我目前正在尝试:

select r2.category_id
from category_item r1, category_item r2
where r1.category_id = ?
    and r2.category_id <> r1.category_id
    and r1.item_id = r2.item_id

构建 table:

A   1   B   1
A   1   C   1
A   1   D   1
A   1   E   1
A   2   B   2
A   2   D   2
A   2   E   2

但我不知道如何继续...


我正在使用 MySQL 5.7,但我只想使用通用的 SQL。

请注意,这不是作业(我也不认为任何老师会布置这么复杂的作业),它只是针对现实世界问题的一个额外简化的用例

为什么不使用 Group_Concat() 然后分组?

select ColA, group_concat(ColB order by ColB separator '|') as concat_line
from CategoryItem
group by ColA

如果你把它停在某个地方,你可以将它与它本身进行比较。

您也可以使用子查询和 exists/not exists

Select Distinct category_id 
from category_item ci
Where not exists   -- this allows only cats that do not have all req items
      (select * from category_item
       Where category_id = ci.category_id 
         and item_id Not in 
            (Select item_id from category_item
             Where category_Id = @catId))
  and not exists   -- this filters out cats that have xtra items
      (Select * from category_item
       Where category_Id = @catId
          and item_id Not in
            (Select item_id from category_item
             Where category_Id = ci.category_Id )) 
  and category_Id <> @catId -- <- categoryId of category you are matching
                            -- this line filters out the category you are 
                            -- matching against. Remove it if you want all
                            -- homologous categories

解释:

Select All distinctCategory_Ids from the join table where: First subquery: where there is not another join table row for that same category with anItem_idthat is *not* in the set ofItem_ids for the category you are matching against, and Second subquery: where there is not an item in the category you are matching against that is not also in the category you are selecting (ci table)