2015-10-20 122 views
1

我有两个表:排除记录,如果右表匹配

一个

+--+----+ 
|id|name| 
+--+----+ 
|0 |foo | 
|1 |bar | 
|2 |baz | 
+-------+ 

+--+----+ 
|A |cond| 
+--+----+ 
|0 |X | 
|1 |Y | 
+-------+ 

哪里BA列A.id值。

我想从一个其中表时B.cond =“X”不匹配选择所有的行。

所以,结果应该是:

  • 巴兹

如何写这个SQL请求,加入(或类似性能的方法)?

回答

2
SELECT 
    A.* 
FROM 
    A 
LEFT JOIN 
    B 
    ON A.id = B.A 
    AND B.cond = 'X' 
WHERE 
    B.A IS NULL 

此查询连接根据您指定的条件表,然后只选择那里的表B没有匹配的行。

5

您可以使用NOT EXISTS

SELECT a.id, a.name 
FROM A 
WHERE NOT EXISTS 
(
    SELECT 1 FROM B 
    WHERE b.A = a.id AND b.cond = 'X' 
) 

但是,我总是忘了MySQL是唯一的(?)RDBMS其中有问题,以优化的EXISTS/NOT EXISTS。所以使用LEFT JOIN方法会更有效率。

http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/

在MS SQL-服务器,最好使用NOT EXISTS

http://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join

+0

关于性能问题,不存在与JOIN更少,更好或相等? – bux

+0

@bux为什么不吸它,看看? – Strawberry

+0

@bux您可能会发现这篇文章很有趣:http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/虽然它可能是稍微过时了。 – jpw

1

除了提出的解决方案,使用not in将工作太:

SELECT * FROM A 
WHERE ID NOT IN (SELECT A FROM B WHERE COND = 'X') 

应该看齐一个left join执行,是更紧凑一点。

+0

我没有考虑过这种方法。感谢分享! –