繁体   English   中英

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

[英]Find rows matching only one of two values

我有两个表, LatestOrdersOrders ,除其他外,两个表都有OrderIdOrderItemId两列。

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

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

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

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

因此,作为示例,假设上表是Orders表,而下表是LatestOrders表:

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

结果将需要189315 ,因为OrderIdOrders表中,但其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

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

LatestOrders您需要查找在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
+---------+-------------+

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 |
+---------+-------------+

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

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

我想使用两个字段进行左联接,然后删除外部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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM