MySQL:查询互斥记录集

时间:2015-01-26 23:12:59

标签: mysql performance

我有一个类似于这个的mysql表:

+----+----------+----------+
| id | first    | last     +
+----+----------+-----------
|  5 | Alan     | Smith    |
|  5 | Bob      | Jones    |
|  5 | Tom      | Clark    |
|  5 | Victor   | Mars     |
|  6 | Bob      | Jones    |
|  6 | Tom      | Kelly    |
|  6 | Victor   | Mars     |
+----+----------+----------+

我想找到一个有效的查询,可以返回id 5和id 6之间不匹配的所有记录......如下所示:

+----+----------+----------+
| id | first    | last     +
+----+----------+-----------
|  5 | Alan     | Smith    |
|  5 | Tom      | Clark    |
|  6 | Tom      | Kelly    |
+----+----------+----------+

目前,我正在使用2个单独的查询,这些查询返回2个不同的“不在”设置,看起来像下面的选择。其中5不在6,而6不在5。

select id,
       first,
       last
  from mytable
 where id = 5  # swap 5 and 6
   and concat(first, last) 
       not in ( select concat(first, last) 
                  from mytable
                where id = 6 )   # swap 5 and 6
      group by id,
               first,
               last

有没有办法在单个查询中获取这两个集合,您是否可以使用此示例数据提供示例?

有没有比我的查询更有效的方法?另外,举个例子。感谢

2 个答案:

答案 0 :(得分:1)

试试这个。它进行自我加入,并使用LEFT联接查看是否没有匹配。如果表的第二个实例(mt2)中没有匹配项,则该表中的所有字段都将返回NULL。由于我猜测id字段是表中的主键,我猜它永远不应该是NULL

select mt1.id,
       mt1.first,
       mt1.last

from mytable mt1

     LEFT JOIN mytable mt2
     ON mt1.first = mt2.first
     AND mt1.last = mt2.last
     AND mt2.id IN (5, 6)
     AND mt1.id <> mt2.id

where mt1.id IN (5, 6)
     AND mt2.id IS NULL
;

答案 1 :(得分:1)

我使用id来表示自动递增的PK。这显然不是这里的情况所以我为了自己的理解而重新命名了这个专栏...

SELECT x.*  
  FROM my_table x 
  LEFT 
  JOIN my_table y 
    ON y.group_id <> x.group_id 
   AND y.first = x.first 
   AND y.last = x.last 
 WHERE x.group_id IN(5,6) 
   AND y.group_id IS NULL;