Need a way to find matches between two many-to-many-relationships

前端 未结 3 1624
Happy的楠姐
Happy的楠姐 2021-01-29 12:11

Given the following tables:

   ------------     ------------
   |     BA   |     |    CA    | 
   ------+-----     ------+-----
   | BId|| AId|     | CId|| AId|
         


        
3条回答
  •  南笙
    南笙 (楼主)
    2021-01-29 12:42

    The number of elements can be calculated using a CTE for CA and BA. Then you can get at the full rows via:

    SQL

    with ca_info as (
          select
               cid
             , count(*) as ccount
            from ca
          group by cid
      ),
    ba_info as (
          select
               bid
             , count(*) as bcount
            from ba
          group by bid
      )
    select
    *
    from
        ba
        join ca on (ba.aid = ca.aid)
        join ba_info on ba.bid=ba_info.bid
        join ca_info on ca.cid=ca_info.cid
    where ccount = bcount
    

    SQL Fiddle

    Results
    bid     aid     cid     aid     bid     bcount  cid     ccount
    B1      2       C2      2       B1      2       C2      2
    B1      3       C2      3       B1      2       C2      2
    

    If you are just interested in C2 itself, you can restrict the result set more:

    with ca_info as (
          select
               cid
             , count(*) as ccount
            from ca
          group by cid
      ),
    ba_info as (
          select
               bid
             , count(*) as bcount
            from ba
          group by bid
      )
    select
    distinct ca.cid
    from
        ba
        join ca on (ba.aid = ca.aid)
        join ba_info on ba.bid=ba_info.bid
        join ca_info on ca.cid=ca_info.cid
    where ccount = bcount
    

    Supersets

    To also get sub/supersets, the condition enforcing the set-equality can be changed:

    where ccount <= bcount
    

    This returns all sets where Bx as at least as many elements as Cy:

    bid    aid    cid    aid    bid    bcount    cid    ccount
    B1     2      C1     2      B1     2          C1    1
    B1     2      C2     2      B1     2          C2    2
    B1     3      C2     3      B1     2          C2    2
    B2     2      C1     2      B2     3          C1    1
    B2     2      C2     2      B2     3          C2    2
    B2     4      C3     4      B2     3          C3    2
    B2     5      C3     5      B2     3          C3    2
    

提交回复
热议问题