【问题标题】:Many to many table queries多对多表查询
【发布时间】:2010-09-12 20:32:53
【问题描述】:

我有一个多对多索引表,我想对其进行包含/排除类型查询。

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? (回答 eid 2 和 5)
  2. 哪些 eid 具有 FID C 而不是 A? (回答 eid 2)

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

我尝试过这样的自我加入:

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

这行不通,因为它仍会返回 eid=1 和 fid=C 的行。

我清楚我想要什么吗?

【问题讨论】:

    标签: sql join


    【解决方案1】:

    使用set subtraction

    Select eid from t where fid = 'B' 
    EXCEPT
    select eid from t where fid = 'A'
    

    【讨论】:

    • 很棒的提示;我实际上从未使用过 EXCEPT 语法。
    【解决方案2】:

    这是一个查询 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】:

      您可以使用子选择

      select eid from t where fid = 'C' and eid not in(select eid from t where fid = 'A')

      【讨论】:

        【解决方案4】:

        MySQL 5.0 支持存在/不存在的位置,如 Nigel 和 Mike 所述。

        【讨论】:

          【解决方案5】:

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

          选择 t1.eid 从#test t1 左连接 ( 选择开斋节 来自#test t2 其中fid ='A' 按开斋节分组 ) t2 上 t2.eid = t1.eid 其中 t1.fid = 'B' 并且 t2.eid 为空

          【讨论】:

            【解决方案6】:

            应该可以在不使用子查询的情况下做到这一点:

            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】:

              查看 MINUS 运算符。它像 UNION 一样工作,除了它减去 UNION 添加的位置。上一个带有“EXCEPT”一词的答案可能是同一事物的不同关键字。

              这是一个未经测试的答案:

              select eid 
              from t
              where fid = 'A'
              minus
              select eid
              from t
              where fid = 'B'
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2020-10-07
                • 2019-11-10
                • 2012-08-17
                • 1970-01-01
                • 1970-01-01
                • 2019-12-09
                • 2020-03-26
                相关资源
                最近更新 更多