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

获取支持SQL中所有交付模式的产品,sql,sql-server,relational-division,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

我有一个表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 
我在解决方案中看到的问题是,人们应该知道交付模式的总数。通过从子查询中获取计数,我们可以使计数动态化


有更好的解决方案吗?

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

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

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

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

请参阅。

您可以使用下面的查询以获得更好的性能

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

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

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

“更好的解决方案”关于什么?可维护性?效率?如果是后者,那么包含索引的表定义是什么?是否还有其他具有不同交付模式的表格?不过,您可能会发现以下文章很有用。嗯,好主意。我打算使用一个表变量来存储不同的DeliveryID,但这样更好。:)@Kahn,实际上table变量是一个很好的选择,因为在某些情况下,
CTE
可能会导致性能问题。