![](/img/trans.png)
[英]Oracle SQL. Find Matching values in two different columns and different rows from same table or different one
[英]Find rows matching only one of two values
我有两个表, LatestOrders
和Orders
,除其他外,两个表都有OrderId
和OrderItemId
两列。
每个OrderId
都有一个或多个OrderItemId
,如下所示:
+---------+-------------+
| OrderId | OrderItemId |
+---------+-------------+
| 5062154 | 187503 |
| 5063171 | 188697 |
| 5063670 | 189314 |
| 5063670 | 189315 |
+---------+-------------+
如您所见,虽然5062154和5063171只有一个OrderItemId
,但5063670有两个。
我试图在Orders
表中找到所有OrderItemId
,它们的OrderId
也在LatestOrders
表中,但没有匹配的OrderItemId
。
因此,作为示例,假设上表是Orders
表,而下表是LatestOrders
表:
+---------+-------------+
| OrderId | OrderItemId |
+---------+-------------+
| 5062154 | 187503 |
| 5063171 | 188697 |
| 5063670 | 189314 |
| 5063698 | 189401 |
+---------+-------------+
结果将需要189315 ,因为OrderId
在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
编辑:我忘了提的是, 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.