2013-05-30 46 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上查看结果。

也有看看这个答案:

相关问题