2011-10-12 54 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,这可能会产生意想不到的结果)。

相关问题