【问题标题】:Find rows matching only one of two values查找仅匹配两个值之一的行
【发布时间】:2018-06-13 18:45:01
【问题描述】:

我有两张表,LatestOrdersOrders,它们都有两列,OrderIdOrderItemId

每个OrderId 都有一个或多个OrderItemIds,如下所示:

+---------+-------------+
| OrderId | OrderItemId |
+---------+-------------+
| 5062154 |      187503 |
| 5063171 |      188697 |
| 5063670 |      189314 |
| 5063670 |      189315 |
+---------+-------------+

如您所见,50621545063171 只有一个 OrderItemId,而 5063670 有两个。

我试图在Orders 表中找到所有OrderItemIds,它们的OrderId 也在LatestOrders 表中,但没有匹配的OrderItemId

因此,例如,假设上面的表是Orders 表,下面是LatestOrders 表:

+---------+-------------+
| OrderId | OrderItemId |
+---------+-------------+
| 5062154 |      187503 |
| 5063171 |      188697 |
| 5063670 |      189314 |
| 5063698 |      189401 |
+---------+-------------+

结果我需要 189315,因为 OrderIdOrders 表中,但它的 OrderItemId 不在。

我可以通过以下查询获得所有 OrderIds 的列表,但我似乎无法找到如何操作它以返回 OrderItemIds。

WITH cte1
     AS (
     SELECT OrderId
          , COUNT(OrderId) AS Count
     FROM Orders
     GROUP BY OrderId),
     cte2
     AS (
     SELECT OrderId
          , COUNT(OrderId) AS Count
     FROM LatestOrders
     GROUP BY OrderId)
     SELECT *
     FROM cte1 c1
          FULL OUTER JOIN cte2 c2 ON c1.OrderId = c2.OrderId
     WHERE c1.Count <> c2.Count

编辑:我忘了提到Orders 表比LatestOrders 表包含更多的订单,我不想找到LatestOrders 中的所有订单表而不是 Orders 表中。我要查找的是两个表中的所有订单,但在LatestOrders 表中没有匹配的OrderItemId

【问题讨论】:

    标签: sql sql-server sql-server-2017


    【解决方案1】:

    鉴于您需要找到LatestOrders 中存在OrderId 确实,但OrderItemId 不存在 的行,您不能做一个简单的LEFT JOIN 并按照其他人的建议排除 NULL。该解决方案将包括您要查找的行,但也将包括 OrderId 根本不在 LatestOrders 中的行。

    最简单的方法是进行两次EXISTS 检查,一次检查OrderId 是否在LatestOrders 中,另一次检查OrderId, OrderItemId 组合是否。这是一个潜在的查询:

    SELECT  O.*
    FROM    Orders O
    WHERE EXISTS (SELECT 1 FROM LatestOrders LO WHERE O.OrderId = LO.OrderId)
    AND NOT EXISTS (SELECT 1 FROM LatestOrders LO WHERE O.OrderId = LO.OrderId AND O.OrderItemId = LO.OrderItemId)
    

    示例

    订单

    +---------+-------------+
    | OrderId | OrderItemId |
    +---------+-------------+
    | 5062154 |      187503 |
    | 5063171 |      188697 |
    | 5063670 |      189314 |
    | 5063670 |      189315 | <- OrderId exists in LatestOrders but OrderItemId does not
    | 5063613 |      189395 | <- OrderId doesn't exist in LatestOrders
    +---------+-------------+
    

    最新订单

    +---------+-------------+
    | OrderId | OrderItemId |
    +---------+-------------+
    | 5062154 |      187503 |
    | 5063171 |      188697 |
    | 5063670 |      189314 |
    | 5063670 |      189417 | <- OrderId exists in Orders but OrderItemId does not
    | 5063698 |      189401 | <- OrderId doesn't exist in Orders
    +---------+-------------+
    

    结果

    +---------+-------------+
    | OrderId | OrderItemId |
    +---------+-------------+
    | 5063670 |      189315 |
    +---------+-------------+
    

    【讨论】:

    • 玩得很好,+1 解释了为什么它飞到我的头上。
    【解决方案2】:

    您可以在 OrderItemId 上使用左连接并检查空值

    select a.OrderItemId
    from Orders a 
    left join LatestOrders  b on a.OrderItemId = b.OrderItemId 
    where b.OrderItemId is null  
    

    【讨论】:

      【解决方案3】:

      我想使用两个字段的左连接然后删除外部空值应该可以解决问题。

      SELECT 
          OrderID,
          OrederItemID
      FROM
          Orders O
          LEFT JOIN LatestOrders LO ON LO.OrderID=O.OrderID AND LO.OrderItemID=O.OrderItemID
      WHERE
          LO.OrderID IS NULL
      

      【讨论】:

        【解决方案4】:

        你有这个答案,但当我开始研究它时它没有出现。
        进行左连接并测试是否为空。

        declare @o table(OrderId int, OrderItemId int);
        insert @o values 
        (5062154, 187503),
        (5063171, 188697),
        (5063670, 189314),
        (5063670, 189315);
        declare @ol table(OrderId int, OrderItemId int);
        insert @ol values 
        (5062154, 187503),
        (5063171, 188697),
        (5063670, 189314),
        (5063698, 189401);
        
        select o.* 
        from @o o
        left join @ol ol
          on o.OrderId     = ol.OrderId 
         and o.OrderItemId = ol.OrderItemId 
        where ol.OrderId is null
        

        【讨论】:

          猜你喜欢
          • 2015-05-23
          • 1970-01-01
          • 2016-09-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多