查找仅匹配两个值之一的行

Find rows matching only one of two values

我有两个 table,LatestOrdersOrders,它们都有两列,OrderIdOrderItemId

每个 OrderId 都有一个或多个 OrderItemId,像这样:

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

如你所见,50621545063171只有一个OrderItemId5063670有两个。

我正在尝试查找 Orders table 中的所有 OrderItemId,他们的 OrderId 也在 LatestOrders table 中] 但没有匹配 OrderItemId.

所以,举个例子,上面的table是Orderstable,下面是LatestOrderstable:

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

我需要 189315 作为结果,因为 OrderIdOrders table 中,但它的 OrderItemId 不是。

我可以通过下面的查询获得所有这些 OrderId 的列表,但我似乎无法找到如何将其操作为 return 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 table 包含的订单比 LatestOrders table 多得多,我不想找到 LatestOrders table 中的所有订单,而不是 Orders table 中的所有订单。我要查找的是 table 中的所有订单,但在 LatestOrders table.

中没有匹配的 OrderItemId

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

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

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

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

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

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

鉴于您需要查找 OrderId 存在于 LatestOrders 中但 OrderItemId 存在的行not,你不能像其他人建议的那样做一个简单的 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 |
+---------+-------------+