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

时间:2018-06-13 18:45:01

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

我有两个表,LatestOrdersOrders,其中包括两列OrderIdOrderItemId

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

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

如您所见,虽然 5062154 5063171 只有一个OrderItemId,但 5063670 有两个。

我试图在OrderItemId表格中找到Orders所有OrderId也在LatestOrders表中但没有匹配的OrderItemId Orders }}

因此,举例来说,上表是LatestOrders表,下面是+---------+-------------+ | OrderId | OrderItemId | +---------+-------------+ | 5062154 | 187503 | | 5063171 | 188697 | | 5063670 | 189314 | | 5063698 | 189401 | +---------+-------------+ 表:

OrderId

我需要 189315 ,因为Orders位于OrderItemId表中,但其OrderId不是。

我可以通过下面的查询获取所有这些OrderItemId的列表,但我似乎无法找到如何操纵它来返回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 s

Orders

编辑:我忘了提及LatestOrders表包含的订单多于LatestOrders表,我不想查找所有订单在Orders表中,而不在OrderItemId表中。我尝试查找的是两个表格中的所有订单,但LatestOrders表格中没有匹配的{{1}}。

4 个答案:

答案 0 :(得分:3)

看到您需要找到OrderId中存在LatestOrders 的行,但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
+---------+-------------+

<强> 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 :(得分:0)

你可以在OrderItemId上使用左边的joiun并检查空值

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

你有这个答案,但是当我开始研究时,它没有起来 执行左连接并测试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