Reputation: 3143
I have a details table and I want to get the record that exactly matches the list of values in another table. Here is a scenario:
OrderDetailTable
OrderID ItemID
1 1
1 2
1 3
1 4
2 1
2 2
2 4
3 1
3 2
3 3
4 1
4 2
OrderedTable
ItemID
1
2
Now I want to get the OrderID that has the exact ItemID matches with OrderedTable ItemID. In the above scenario OrderID 1 is valid since ItemID 1,2,3 is exactly matched with OrderedTable ItemID.
I used the join but it did not work. It gave me both OrderID 1,2 . How do I do it any ideas??
Upvotes: 0
Views: 3007
Reputation: 52107
Try this:
SELECT OrderID
FROM OrderDetailTable JOIN OrderedTable USING (ItemID)
GROUP BY OrderID
HAVING COUNT(DISTINCT ItemID) = (SELECT COUNT(DISTINCT ItemID) FROM OrderedTable)
The idea, in a nutshell, is as follows:
If these two numbers are equal, the given OrderID "contains" all ItemIDs. If the one is smaller than the other, there is at least one ItemID not contained in the given OrderID.
Depending on your primary keys, the DISTINCT
may not be necessary (though it doesn't hurt).
Upvotes: 1
Reputation: 70369
try
SELECT * FROM OrderDetailTable WHERE OrderID NOT IN
(
SELECT A.OrderID FROM
(
SELECT
Y.OrderID
, OT.ItemID
, (SELECT Z.ItemID
FROM OrderDetailTable Z
WHERE Z.ItemID = OT.ItemID AND Z.OrderID = Y.OrderID
) I
FROM OrderDetailTable Y, OrderedTable OT
) A
WHERE A.I IS NULL);
EDIT - as per request the better syntax:
SELECT * FROM
OrderDetailTable Z WHERE Z.ORDERID NOT IN
(
SELECT O1 FROM
(SELECT Y.ORDERID O1, YY.ORDERID O2 FROM
OrderDetailTable Y CROSS JOIN OrderedTable OT
LEFT OUTER JOIN OrderDetailTable YY ON
YY.ORDERID = Y.ORDERID AND YY.ITEMID = OT.ITEMID ) ZZ WHERE ZZ.O2 IS NULL);
Upvotes: 0