oracle sql 比较两个子选择的结果
oracle sql compare result two subselects
假设我的发票有两个 Oracle SQL 表。 INV_HEAD 用于地址、日期、...
然后我对发票的每个位置都有INV_POS。
INV_HEAD
--------
id
date
adr_id
total
INV_POS
---------
id
he_id
pos
art_id
quantity
price
我可以列出所有发票
SELECT he.id, he.date, po.art_id, po.quantity, po.price
FROM INV_HEAD he
JOIN INV_POS po on po.he_id = he.id
现在我想查找相同位置的发票,不一定是相同的顺序。我该怎么做?
因此我只需要具有相同位置的所有发票的INV_HEAD.id。
这是相同的示例数据:
id | he_id | pos | art_id | quantity | price
1 | 1 | 1 | 1000 | 5 | 100.00
2 | 1 | 2 | 2000 | 10 | 5000.00
3 | 2 | 1 | 2500 | 2 | 1250.00
4 | 3 | 1 | 2000 | 10 | 5000.00
5 | 3 | 2 | 1000 | 5 | 100.00
he_id 1 和 3 的发票具有相同的位置。
您可以使用解析函数 LISTAGG 将 id 与相同位置连接起来
SELECT p.pos, LISTAGG(h.id, ', ') WITHIN GROUP (ORDER BY p.pos) "Id"
FROM inv_head h, inv_pos p
where h.id=p.he_id
group by p.pos;
您将得到以下结果
销售点编号
1 | 1、2、3
2 | 1、3
我看不出加入 inv_head 的原因,但我坚持了您最初的查询(可能您有此意图)。
你想要这样的东西(注意下一个查询不起作用,因为我们不能使用 = 比较集合):
SELECT SELECT DISTINCT H1.ID, H2.ID
FROM INV_HEAD H1, INV_HEAD H2
WHERE H1.ID <> H2.ID AND
(SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID) =
(SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H2.ID)
但是我们可以重新思考这个问题:A = B也意味着A-B UNION B-A是一个空集。
因此,您可以使用 NOT EXISTS((A MINUS B) UNION (B MINUS A)) 而不是 A = B
其中 A 是 (SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID) 和 B 是 (SELECT ART_ID, 数量, 价格来自 INV_POS WHERE HE_ID = H2.ID)
所以您的查询是:
SELECT DISTINCT H1.HE_ID, H2.HE_ID
FROM INV_HEAD H1, INV_HEAD H2
WHERE H1.ID <> H2.ID
AND NOT EXISTS(
((SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID)
MINUS
(SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H2.ID))
UNION
((SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H2.ID)
MINUS
(SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID)));
此查询创建了具有相同位置的发票对(请注意,如果两张发票没有位置,则它们被视为相等)。
条件 H1.ID <> H2.ID 避免了像 (1, 1) 或 (3, 3) 这样的对。但是如果你有对 (1,3) 你也会有对称的 (3,1)。如果您想避免对称,请改用 H1.ID < H2.ID 或 H1.ID > H2.ID。
如果您想知道与 ID = X 的给定发票具有相同位置的发票,请使用 WHERE H1.ID = X AND H1.ID <> H2.ID AND.. (使用 <>,在这种情况下不要使用 < 或 >)。
假设我的发票有两个 Oracle SQL 表。 INV_HEAD 用于地址、日期、... 然后我对发票的每个位置都有INV_POS。
INV_HEAD
--------
id
date
adr_id
total
INV_POS
---------
id
he_id
pos
art_id
quantity
price
我可以列出所有发票
SELECT he.id, he.date, po.art_id, po.quantity, po.price
FROM INV_HEAD he
JOIN INV_POS po on po.he_id = he.id
现在我想查找相同位置的发票,不一定是相同的顺序。我该怎么做?
因此我只需要具有相同位置的所有发票的INV_HEAD.id。
这是相同的示例数据:
id | he_id | pos | art_id | quantity | price
1 | 1 | 1 | 1000 | 5 | 100.00
2 | 1 | 2 | 2000 | 10 | 5000.00
3 | 2 | 1 | 2500 | 2 | 1250.00
4 | 3 | 1 | 2000 | 10 | 5000.00
5 | 3 | 2 | 1000 | 5 | 100.00
he_id 1 和 3 的发票具有相同的位置。
您可以使用解析函数 LISTAGG 将 id 与相同位置连接起来
SELECT p.pos, LISTAGG(h.id, ', ') WITHIN GROUP (ORDER BY p.pos) "Id"
FROM inv_head h, inv_pos p
where h.id=p.he_id
group by p.pos;
您将得到以下结果
销售点编号
1 | 1、2、3
2 | 1、3
我看不出加入 inv_head 的原因,但我坚持了您最初的查询(可能您有此意图)。
你想要这样的东西(注意下一个查询不起作用,因为我们不能使用 = 比较集合):
SELECT SELECT DISTINCT H1.ID, H2.ID
FROM INV_HEAD H1, INV_HEAD H2
WHERE H1.ID <> H2.ID AND
(SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID) =
(SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H2.ID)
但是我们可以重新思考这个问题:A = B也意味着A-B UNION B-A是一个空集。
因此,您可以使用 NOT EXISTS((A MINUS B) UNION (B MINUS A)) 而不是 A = B 其中 A 是 (SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID) 和 B 是 (SELECT ART_ID, 数量, 价格来自 INV_POS WHERE HE_ID = H2.ID)
所以您的查询是:
SELECT DISTINCT H1.HE_ID, H2.HE_ID
FROM INV_HEAD H1, INV_HEAD H2
WHERE H1.ID <> H2.ID
AND NOT EXISTS(
((SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID)
MINUS
(SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H2.ID))
UNION
((SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H2.ID)
MINUS
(SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID)));
此查询创建了具有相同位置的发票对(请注意,如果两张发票没有位置,则它们被视为相等)。
条件 H1.ID <> H2.ID 避免了像 (1, 1) 或 (3, 3) 这样的对。但是如果你有对 (1,3) 你也会有对称的 (3,1)。如果您想避免对称,请改用 H1.ID < H2.ID 或 H1.ID > H2.ID。
如果您想知道与 ID = X 的给定发票具有相同位置的发票,请使用 WHERE H1.ID = X AND H1.ID <> H2.ID AND.. (使用 <>,在这种情况下不要使用 < 或 >)。