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