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.. (使用 <>,在这种情况下不要使用 < 或 >)。