代码之家  ›  专栏  ›  技术社区  ›  Pyrolistical

多对多表查询

  •  2
  • Pyrolistical  · 技术社区  · 17 年前

    fid实际上是一个整数索引,但为了便于理解,这里将其作为字母。下面是一个示例表:

    表t

    eid | fid
    ----+----
    1   | A
    1   | B
    1   | C
    2   | B
    2   | C
    3   | A
    3   | C
    4   | A
    4   | B
    5   | B
    

    1. 什么样的EID有fid B,而不是A?(答复2和5)
    2. 什么样的EID有fid C,而不是A?(答复二)

    我似乎想不出一个查询可以做到这一点。

    我尝试过这样的自连接:

    select * 
    from t as t1 
    join t as t2 
    where t1.eid=t2.eid 
      and t1.fid!=t2.fid 
      and t1.fid=B and t2.fid!=A
    

    我清楚我想要什么吗?

    7 回复  |  直到 12 年前
        1
  •  7
  •   Tom Ritter    17 年前

    set subtraction

    Select eid from t where fid = 'B' 
    EXCEPT
    select eid from t where fid = 'A'
    
        2
  •  3
  •   ConcernedOfTunbridgeWells    17 年前

    下面是一个查询1的示例(2的工作原理基本相同)

    select t1.eid
      from t t1
     where t1.fid  = 'B'
       and not exists
           (select 1
              from t t2
             where t2.eid = t1.eid
               and t2.fid  = 'A')
    
        3
  •  1
  •   Mike J    17 年前

        4
  •  0
  •   John Rudy    17 年前

    MySQL 5.0 支持where exists/where not exists,如Nigel和Mike所述。

        5
  •  0
  •       17 年前

    具有可能比使用更快的直连接的版本存在:

    Select  t1.eid
    From    #test t1
            left join (
                Select  eid
                From    #test t2 
                Where   fid = 'A'
                Group by eid
            ) t2 on t2.eid = t1.eid 
    Where   t1.fid = 'B'
            and t2.eid is null
    
        6
  •  0
  •   Bill Karwin    17 年前

    不使用子查询也可以执行此操作:

    SELECT DISTINCT t1.eid
    FROM table1 AS t1
      LEFT JOIN table1 AS t2 ON (t1.eid = t2.eid AND t2.fid = 'A')
    WHERE t2.eid IS NULL
      AND t1.fid = 'B';
    

    要执行第二个示例搜索,只需将值“B”更改为“C”。

        7
  •  0
  •   Walter Mitty    17 年前

    查看减号运算符。它的工作原理类似于并集,只是它在并集相加的地方进行减法。上一个答案中的“除外”可能是同一事物的不同关键字。

    以下是一个未经检验的答案:

    select eid 
    from t
    where fid = 'A'
    minus
    select eid
    from t
    where fid = 'B'
    
    推荐文章