2011-10-12 55 views
2

我有2個表:從一個表使用的信息以便發現信息在另一個表中存在

廣告:

+------+---------------+ 
| ID | Name   | 
+------+---------------+ 
| 1 | Item 1  | 
| 2 | Item 2  | 
| 3 | Item 3  | 
| 4 | Item 4  | 
| 5 | Item 5  | 
+------+---------------+ 

assigned_ads:

+------+-----------+--------------+ 
| ID | ad_id | location | 
+------+-----------+--------------+ 
| 1 | 3  | place 1  | 
| 2 | 2  | place 2  | 
| 3 | 1  | place 3  | 
+------+-----------+--------------+ 

正如你所看到的; ad 1,2和3都被分配到一個位置。我需要的是一個查詢,獲取未在assigned_ads表分配ads表中的所有行

+0

[從另一個表(JOIN)獲取非現有數據的可能的重複](http://stackoverflow.com/questions/7494586/get-non-existing-disting-from-another-table-join) – onedaywhen

回答

4

您需要使用LEFT OUTER JOIN要做到這一點,如下顯示:

SELECT * 
FROM ads a 
LEFT JOIN assigned_ads aa ON a.ID = aa.ad_id 
WHERE aa.location IS NULL 
+1

「Need至」?與SQL中的大多數事情一樣,執行關係型非存在性限定的方法不止一種。看到我的答案。 – onedaywhen

0

試試這個:

SELECT * 
FROM ads a 
WHERE a.id NOT IN (SELECT ad_id FROM assigned_ads) 
+0

查詢中有幾個拼寫錯誤:'assigned_ad'和'om' – Saket

0

只是用戶左連接查詢和匹配左表ID設置爲NULL。 您查詢應該是這樣的

select * from ads ad left join assigned_ad a_ad ON a_ad.ad_id = ad.id where a_ad.id is null 

更多有關LEFT JOIN諮詢here

1

您還可以使用NOT EXISTS操作:

SELECT * 
FROM ads a 
WHERE NOT EXISTS 
(SELECT * FROM assigned_ads aa WHERE a.ID = aa.ad_id) 
1

您需要的關係運算符是半差異又名antijoin

大多數SQL產品缺少顯式的半連接運算符或關鍵字。標準SQL-92沒有一個(它有一個MATCH (subquery)半連接謂詞,但儘管有其他想法,但NOT MATCH (subquery)的語義與半差異不同; FWIW真正的關係語言Tutorial D成功使用NOT MATCHING半差異) 。

半差異當然可以使用其他SQL謂詞編寫。最常見的是:外連接,WHERE子句中的空值測試,緊接着是EXISTSIN (subquery)。使用EXCEPT(相當於Oracle中的MINUS)是另一種可能的方法,只要您的SQL產品支持該方法,並且依賴於數據(具體而言,兩個表的標題相同)。

個人而言,我更喜歡在SQL中使用EXISTS來進行半差異連接,因爲連接子句在書寫的代碼中更接近,並且不會導致對連接表的投影,例如

SELECT * 
    FROM ads 
WHERE NOT EXISTS (
        SELECT * 
        FROM assigned_ads 
        WHERE ads.ID = assigned_ads.ID 
       ); 

IN (subquery)(同爲外部連接方式),你需要的,如果子查詢中的WHERE條款涉及空值(格外小心提示:如果在子查詢WHERE子句的值爲UNKNOWN由於存在那麼它將被強制爲EXISTS,這可能會產生意想不到的結果)。

相關問題