获取支持SQL中所有交付模式的产品

时间:2013-12-15 18:37:07

标签: sql sql-server relational-division

我有一个表 ProductDeliveryModes

ProductId    DeliveryId
P101         D1
P101         D2
P101         D3
P102         D1
P102         D2
P102         D3
P103         D1

我需要获得支持所有交付模式(D1,D2,D3)的产品。从表格上看,产品应为:P101和P102。

我为获得解决方案而形成的查询是:

SELECT ProductId
FROM   (SELECT DISTINCT ProductId,
                        DeliveryId
        FROM   ProductDeliveryModes) X
WHERE  X.DeliveryId IN ( 'D1', 'D2', 'D3' )
GROUP  BY ProductId
HAVING COUNT(*) = 3 

我在解决方案中看到的问题是,应该知道交付模式总数的计数。我们可以通过从子查询中获取计数来使计数动态化。

有更好的解决方案吗?

3 个答案:

答案 0 :(得分:1)

我相信您可以使用DISTINCT COUNT函数来获得相同的结果:

SELECT [ProductID]
FROM ProductDeliveryModes
GROUP BY  [ProductID]
HAVING COUNT(DISTINCT [DeliveryId]) = 3

检查example

您可以将不同的交货计数简单地存储在变量中并使用它。如果您需要在单个查询中执行此操作,这是可能的方法之一:

WITH CTE (DeliveryCount) AS 
(
   SELECT COUNT(DISTINCT [DeliveryID])
   FROM DataSource
)  
SELECT [ProductID]
FROM DataSource
CROSS APPLY CTE
GROUP BY [ProductID]
        ,CTE.DeliveryCount
HAVING COUNT(DISTINCT [DeliveryID]) = DeliveryCount

请参阅example

答案 1 :(得分:1)

您可以使用以下查询来获得更好的效果。

 ;WITH CTE_Product
 AS
 (
        SELECT DISTINCT ProductID 
        FROM ProductDeliveryModes
 ),CTE_Delivery
 AS
 (
        SELECT DISTINCT DeliveryId 
        FROM ProductDeliveryModes
 )

 SELECT * 
 FROM CTE_Product C
 WHERE NOT EXISTS
 (
     SELECT 1 
     FROM CTE_Delivery D
     LEFT JOIN ProductDeliveryModes T ON T.DeliveryId = D.DeliveryId AND T.ProductId=C.ProductId 
     WHERE T.ProductID IS NULL
 ) 

答案 2 :(得分:1)

您可以稍微修改一下您的查询,以获得不同交付方式的实际数量:

SELECT ProductID
FROM ProductDeliveryModes
GROUP BY ProductID
HAVING COUNT(*) =
   (SELECT COUNT (DISTINCT DeliveryId) FROM ProductDeliveryModes)