2015-10-20 157 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

我沒有考慮過這種方法。感謝分享! –