2015-01-26 90 views
0

我有一个类似的MySQL表:的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 

有没有办法在一个单一的查询来获取两集,您可以提供使用该样本数据的例子吗?

有没有比我的查询更有效的方法?另外,请提供示例。谢谢

+0

是的。是的。尝试! – Strawberry 2015-01-26 23:14:20

回答

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; 
+0

工程,它是干净和简单的,我敢肯定它会比“不在”更有效 – panofish 2015-01-27 14:46:22

+0

应该是在'ON'子句中的'AND y.group_id IN(5,6)'。 – 2015-01-27 19:14:22

+0

@ypercube我也想知道。 – Strawberry 2015-01-27 19:23:55

1

试试这个。它会自行加入,并使用连接来查看是否不匹配。如果在表格的第二个实例(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 
; 
+0

这没有返回任何结果与上面的示例表 – panofish 2015-01-27 14:45:16

+0

我的不好。每一行都是自己匹配的。我修正了上面的代码。 – Tom 2015-01-27 19:10:24