【问题标题】:How to find records from table A, which are not present in table B?如何从表 A 中查找表 B 中不存在的记录?
【发布时间】:2014-02-26 19:09:49
【问题描述】:

我使用 SQL Server 2008 数据库。

我有两个表,列如下:

Table A:

request_id|order_id|e-mail
100       |2567    |jack@abc.com
100       |4784    |jack@abc.com
450       |2578    |lisa@abc.com
450       |8432    |lisa@abc.com
600       |9032    |john@abc.com
600       |9033    |john@abc.com

Table B 也有 idorder_no 列以及许多其他列:

Table B:

request_id|order_id|e-mail
100       |2563    |oscar@abc.com
300       |4784    |peter@abc.com
600       |9032    |john@abc.com
650       |2578    |bob@abc.com
850       |8432    |alice@abc.com

如您所见,表 A 中的给定 request_id 可以出现多次(见 100 和 450 条记录)

我需要查找表 A 中的所有记录,这些记录在表 B 中不存在 order_id,但具有相等的 request_id 列值。

对于上面的例子,我希望是这样的:

Output:

request_id|order_id|e-mail
100       |2567    |jack@abc.com
100       |4784    |jack@abc.com
450       |2578    |lisa@abc.com
450       |8432    |lisa@abc.com
600       |9033    |john@abc.com

如您所见,表 A 中的上述记录在表 B 中不存在。此条件仅满足 order_id=600 的记录

我创建了 T-SQL 查询的草图:

select 
    D.request_id, D.order_id 
from 
    table A AS D 
where 
    D.request_id = 600 
    and D.order_id not in (select M.order_id 
                           from table B AS M 
                           where M.request_id = 600)

不幸的是,我不知道如何为所有request_id 转换我的查询。第一个想法是使用 while 循环遍历表 A 中的所有 request_id,但在 SQL 世界中似乎并不聪明。

感谢您的帮助

【问题讨论】:

    标签: sql database sql-server-2008 tsql


    【解决方案1】:

    试试这个 -

    SELECT a.*
    FROM      table_a a
    LEFT JOIN table_b b ON a.request_id = b.request_id
                       AND a.order_id   = b.order_id
    WHERE b.request_id IS NULL
    

    在这里查看 - SQL Fiddle

    【讨论】:

    • 谢谢。目前我无法在实际示例中对其进行测试,但它似乎有效!一个问题:我是否将最后一个 WHERE 条件更改为“WHERE b.order_id IS NULL”?我发现它也有效,而且对我来说似乎更舒服,因为我想找到所有不匹配的 request_id :)
    • 由于JOIN 子句中使用了两列(request_idorder_id),因此您不需要它。是一样的。
    • 也许我误解了这个要求,但我认为 OP 是说他想要表 B 中有一条记录与 request_id 上的表 A 匹配但不是 order_id 的所有情况。上述查询将列出表 A 中在 request_id 或 order_id 上与表 B 中不匹配的记录。
    • 这与 OPs 问题陈述不匹配:A 中的所有行在请求 id 上与 B 中的匹配,但在请求和订单 id 上都不匹配。
    • @NicholasCarey 这也是我最初认为他的意思。但是再看看他的预期输出。我认为他需要澄清“具有相等的 request_id 列值”的含义。等于什么?
    【解决方案2】:
    select request_id, order_id from table_a
    except
    select request_id, order_id from table_b
    

    编辑:这在 MS SQL 中不起作用:

    如果您也想要电子邮件地址:

    select request_id, order_id, email from table_a
    where (request_id, order_id) not in (
        select request_id, order_id from table_b
    )
    

    【讨论】:

    • 在 MS SQL 中,您需要使用EXCEPT 而不是minus。语法在其他方面是相同的。我不相信第二种方法适用于 T-SQL。您也可以在主键上执行table_a LEFT JOIN table_b,然后是WHERE table_b.<primary_key> IS NULL
    • @BaconBits 我不明白你的第二个解决方案的线索。在这种情况下,primary_key 是什么意思?是 request_id 吗?恕我直言,在 LEFT OUTER JOIN 我只能匹配一个条件的表,那么我如何通过 request_id 和 order_id 进行匹配?谢谢
    • @Viper AgentSQL 的回答正是我所想的。
    • 感谢您指出除了。每天学习新东西;)
    • @BaconBits 谢谢你的帮助。现在我明白了我认为的你的方法
    【解决方案3】:
     SELECT  request_id, order_id,e-mail
      FROM  table_a
      EXCEPT 
      SELECT  request_id, order_id,e-mail
      FROM  table_b
    

    【讨论】:

      【解决方案4】:

      我不确定您所说的“但具有相同的 request_id 列值”是什么意思。等于什么?

      如果您只是想要 table_a 中的所有记录,而 table_b 中没有匹配 request_id 和 order_id 的记录,那么:

      select a.request_id, a.order_id
      from table_a a
      where not exists (select * from table_b b where b.request_id=a.request_id 
        and b.order_id=a.order_id)
      

      【讨论】:

      • 这也使 O.P.s 问题陈述失败。
      • 正如我在本文开头所说的,我认为 OP 需要澄清他的问题陈述。我相信上面的查询将给出 OP 列出的内容作为他的预期输出给定的输入。
      【解决方案5】:

      原始海报的问题陈述是(我引用):

      我需要查找表 A 中的所有记录, order_id 不存在于表 B 中, 但具有相同的 request_id 列值。

      关于 SQL 的事情是它具有强大的数学基础

      • 集合论,以及
      • 谓词演算

      因此,O.P 的问题陈述可以简单地在标准 SQL 中重述,几乎原样:

      select *                                    -- select all rows
      from A a                                    -- from table A 
      where exists (                              -- * that have at least one matching
              select *                            --   row in B with the same request ID
              from B b                            --
              where b.request_id = a.request_id   --
            )                                     --
        and not exists (                          -- * but have no matching row in B
              select *                            --   with the same
              from B b                            --   request AND order IDs
              where b.request_id = a.request_id   --
                and b.order_id   = a.order_id     --
            )                                     --
      

      简单!

      【讨论】:

      • 返回值是否与预期输出匹配?我不这么认为。看看他的OUTPUT
      猜你喜欢
      • 1970-01-01
      • 2013-05-26
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 2020-02-23
      • 2023-03-20
      相关资源
      最近更新 更多