Let's say I have two Oracle SQL tables for my invoices. INV_HEAD for adress, date, ... Then I have INV_POS for every position of the invoice.
INV_HEAD
--------
id
date
adr_id
total
INV_POS
---------
id
he_id
pos
art_id
quantity
price
I can list all the invoices with
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
Now I want to find invoices with the same positions, not necessarily in the same order. How can I do this?
As a result I only need the INV_HEAD.id of all invoices with the same positions.
Here is same sample data:
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
Invoice with he_id 1 and 3 have the same positions.
You want something like (note that the next query does not work, because we cannot compare sets using =):
But we can rethink the problem: A = B also means that A-B UNION B-A is an empty set.
So instead of A = B you can use NOT EXISTS((A MINUS B) UNION (B MINUS A)) where A is (SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID) and B is (SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H2.ID)
So your query is:
This query creates pairs of invoices that have the same positions (note that if two invoices has no positions they are considered equals).
The condition H1.ID <> H2.ID avoids pairs like (1, 1) or (3, 3). But if you have the pair (1,3) you will also have the symmetric (3,1). If you want to avoid symmetry then use H1.ID < H2.ID or H1.ID > H2.ID instead.
If you want to know the invoices with the same position than a given invoice with ID = X then use WHERE H1.ID = X AND H1.ID <> H2.ID AND.. (use <>, never use < or > in this case).