Oracle获取与值列表完全匹配的行

时间:2011-08-22 23:01:27

标签: sql oracle

我有一个详细信息表,我想获得与另一个表中的值列表完全匹配的记录。 这是一个场景:

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

现在我想获得具有与OrderedTable ItemID匹配的确切ItemID的OrderID。在上面的场景中,OrderID 1是有效的,因为ItemID 1,2,3与OrderedTable ItemID完全匹配。

我使用了联接,但它没有用。它给了我两个OrderID 1,2。我怎么做任何想法??

2 个答案:

答案 0 :(得分:1)

试试这个:

SELECT OrderID 
FROM OrderDetailTable JOIN OrderedTable USING (ItemID)
GROUP BY OrderID 
HAVING COUNT(DISTINCT ItemID) = (SELECT COUNT(DISTINCT ItemID) FROM OrderedTable)

简而言之,这个想法如下:

  • 按ItemID计算OrpedTable与OrderDetailTable的匹配数量,
  • 然后将其与OrderedTable中的ItemID总数进行比较。

如果这两个数字相等,则给定的OrderID“包含”所有ItemID。如果一个小于另一个,则给定的OrderID中至少有一个ItemID未包含。

根据您的主键,DISTINCT可能没有必要(尽管没有伤害)。

答案 1 :(得分:0)

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);

编辑 - 根据要求提供更好的语法:

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);