【问题标题】:Get records from Table A, that are not in Table B从表 A 中获取不在表 B 中的记录
【发布时间】:2013-05-26 12:04:18
【问题描述】:

我是 SQL 新手,还不能正确获取此 SQL 查询。我目前有:

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

两张表都有人员记录,包括姓名和地址。我需要获取 tableA 中的所有记录,而不是 tableB。下图基本就是我需要的:

问题是两个人可能有相同的名字,但不同的地址。所以最终,我需要获取 tableA 中所有人员的记录,不包括具有重复名称和地址的重复项。

每个表都有如下列:

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

【问题讨论】:

  • 你能显示表格的结构,这样我们就不用猜名字了吗? :)
  • 大声笑,是的。好主意。 :) 我会编辑问题。
  • 您是说您需要 DISTINCT 名称和地址组合吗?还是您需要为拥有多个地址的人选择一个地址?
  • 我需要 DISTINCT 名称和地址组合。 EX:可能有两个人的名字相同,但我们知道他们是不同的人,因为他们有不同的地址。所以,我需要保留那些可能名称相同但地址不同的人。

标签: mysql sql logic


【解决方案1】:

以下查询将根据全名和地址为您提供 tableA 中不在 tableB 中的所有人员的 id:

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

您可以轻松地编辑此选择以包含您需要的来自 tableA 的任何信息。

【讨论】:

    【解决方案2】:

    你检查过这个优秀的页面吗? 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
    

    【讨论】:

    • 这是我最初拥有的东西的地方 - 但它并没有解决我的问题,即人们拥有相同的名字,但不同的地址。
    • 哈哈是的。该图像有助于绘制我需要的图表 - 在大多数情况下。
    【解决方案3】:

    由于您要加入两个字段,因此您可以选择 ANTI-JOIN (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)回答

    另一个更模糊的解决方案是使用ALL 关键字。和NOT IN很像

    SELECT DISTINCT tablea.* 
    FROM   tablea 
    WHERE 
    
    ( tablea.`full_name`  , tableA.address) 
    
      !=  ALL (SELECT tableb.`full_name`, tableB.address 
               FROM tableb)
    

    DEMO

    【讨论】:

    • 您的答案也很有效,但选择了 Friederike 的答案,因为它是第一个。谢谢
    • @mdance 一个额外的注释。根据所涉及的列的可空性,您将获得两者之间的不同性能特征。见Quassnoi的文章LEFT JOIN / IS NULL vs. NOT IN vs. NOT EXISTS: nullable columns
    • 另一个选项是 NOT IN(参见my answer),它不需要像 NOT EXISTS 选项那样的相关子查询。
    • @ChristianAmmer 谢谢我完全忘记了 MySQL 的 IN 奇怪,所以我更新了我的答案。但是,您应该小心出于性能原因避免相关子查询的含义。正如 Quassanoi 的文章所指出的,所涉及领域的 Nullablitiy 决定了您应该使用哪种解决方案。
    • MySQL 没有任何奇怪之处(至少在这种情况下没有),您可以包含多于一列的子查询(标准说,您可以使用 Mimer SQL-92 validator 检查它)跨度>
    【解决方案4】:

    您可以使用 NOT EXIST 子句。此条件将返回 tableA 中没有给定 full_name 的 tableB 记录的所有记录。

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

    【讨论】:

      【解决方案5】:

      在我看来,用子查询而不是 JOIN 编写这样的查询是合乎逻辑的。而且因为它是一个不相关的子查询,所以与 JOIN 版本应该没有性能差异。

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

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

      也看看这个答案:

      【讨论】:

        猜你喜欢
        • 2020-02-23
        • 1970-01-01
        • 2022-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多