2013-05-30 101 views
2

我是SQL新手,並且尚未能夠正確獲取此SQL查詢。我目前有:從表A中獲取不在表B中的記錄

SELECT * FROM tableA 
LEFT OUTER JOIN tableB 
ON tableA.`full_name` = tableB.`full_name` 
WHERE tableB.`id` IS NULL 

這兩張表都有人的記錄,包含姓名和地址。我需要獲得所有在tableA中的記錄,但不是tableB。下面的圖表基本上是我需要:

Ven Diagram

的問題是,兩個人可以有相同的名稱,但不同的地址。因此,最終,我需要獲取tableA中所有人員的記錄,不包括具有重複名稱和地址的副本。

每個表中的列如下:

SELECT tableA.id FROM tableA 
LEFT OUTER JOIN tableB 
-- people are the same if fullname and adress match 
ON tableA.`full_name` = tableB.`full_name` 
    AND tableA.adress = tableB.adress 
-- filter people that re in tableA only 
WHERE tableB.`id` IS NULL 
-- filter duplicates 
GROUP BY tableA.id 

id,full_name,first_name,last_name,title,phone,address,city,state,postal_code 
+0

你能顯示錶的表結構,所以我們不必猜測的名字? :) –

+0

大聲笑,是的。好主意。 :)我將編輯該問題。 – mdance

+0

你是說你需要DISTINCT名稱和地址組合?或者您是否需要爲擁有多個地址的人選擇一個地址? –

回答

2

不在tableB的基礎上的全名和地址,下面的查詢會給你的人的所有ID在表A您可以輕鬆編輯此selet以包含您從tableA中需要的任何信息。

0

你有沒有檢查過這個優秀的頁面? http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

SELECT * FROM TableA LEFT OUTER JOIN TableB ON TableA.name = TableB.name WHERE TableB.id IS null 
+0

這就是我首先得到的東西 - 但它不能解決我的問題,即讓人們使用同一個姓名,但地址不同。 – mdance

+0

不知何故,我已經看到這個圖像;-) – Kai

+0

大聲笑。該圖像有助於繪製我需要的東西 - 大部分。 – mdance

3

既然你兩個字段加入你的選擇是一個反連接(Friederike S' answer)Not exists

SELECT DISTINCT tablea.* 
FROM tablea 
WHERE NOT EXISTS (SELECT * 
        FROM tableb 
        WHERE tablea.`full_name` = tableb.`full_name` 
          AND tableA.adress = tableB.adress) 

DEMO

您還可以使用not in見(Christian Ammer's)答案

另一個mor晦澀的解決方案是使用ALL關鍵字。這非常類似於NOT IN

SELECT DISTINCT tablea.* 
FROM tablea 
WHERE 

(tablea.`full_name` , tableA.address) 

    != ALL (SELECT tableb.`full_name`, tableB.address 
      FROM tableb) 

DEMO

+0

你的答案也適用,但選擇Friederike的答案是因爲它是第一個答案。謝謝 – mdance

+1

@mdance一個額外的說明。根據所涉及列的空白性,您將在兩者之間獲得不同的性能特徵。請參見Quassnoi的文章[LEFT JOIN/IS NULL與NOT IN AND NOT EXISTS:nullable columns](http://planet.mysql.com/entry/?id=24888) –

+0

另一個選項是NOT IN(請參閱[我的答案](http://stackoverflow.com/a/16846165/237483)),它不需要像NOT EXISTS選項那樣的相關子查詢。 –

0

您可以使用NOT EXIST子句。此條件將返回tableA中所有記錄都不存在於給定full_name的tableB中的記錄。

SELECT * FROM 
    tableA 
    WHERE 
    NOT EXISTS (select * from tableB Where tableA.full_name = tableB.full_name); 
3

在我看來,用子查詢而不是JOIN編寫這樣的查詢是合乎邏輯的。而且由於它是不相關的子查詢,JOIN版本不應該有性能差異。

SELECT * 
FROM tableA 
WHERE (full_name, address) NOT IN 
(SELECT full_name, address FROM tableB); 

您可以在SQL Fiddle上查看結果。

也有看看這個答案:

相關問題