oracle sql比较结果有两个子选择

时间:2015-06-09 08:36:08

标签: oracle subquery

假设我的发票有两个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的发票具有相同的位置。

2 个答案:

答案 0 :(得分:1)

您可以使用分析函数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;

您将获得以下结果

POS ID

1 | 1,2,3

2 | 1,3,

我没有看到加入inv_head的原因,但是我坚持你的原始查询(可能你有一些意图)。

答案 1 :(得分:0)

你想要的东西(注意下一个查询不起作用,因为我们无法使用=来比较集合):

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是一个空集。

所以代替A = B你可以使用NOT EXISTS((A MINUS B)UNION(B减A)) 其中A是(SELECT ART_ID,QUANTITY,PRICE FROM INV_POS WHERE HE_ID = H1.ID),B是(SELECT ART_ID,QUANTITY,PRICE FROM 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&lt;&gt; H2.ID避免像(1,1)或(3,3)这样的对。但如果你有对(1,3)你也会有对称(3,1)。如果你想避免对称,那么使用H1.ID&lt; H2.ID或H1.ID&gt;而是H2.ID。

如果您想知道具有与ID = X的给定发票相同位置的发票,则使用WHERE H1.ID = X AND H1.ID&lt;&gt; H2.ID AND ..(使用&lt;&gt;,在这种情况下永远不要使用&lt;或&gt;)。