获取支持SQL中所有交付模式的产品
我有一个表ProductDeliveryModes,如下所示:获取支持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
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
可能会导致性能问题。