[英]Dynamic Multi-Column SQL
我有兩個具有如下結構的表:
過道| ItemId | ConfigId | InventSizeId | InventColorId | InventLocationId | DataAreaId | VelocityCategory
ItemId | ConfigId | InventSizeId | InventColorId | InventLocationId | DataAreaId | 銷售
基本表中的每一行都代表一個SKU,並且相關SalesCount記錄的“銷售”字段的總和決定了“選擇”。 該查詢有效:
SELECT Aisle, COUNT(*) as '# SKUs',
SUM(Sales) as '# Picks',
SUM(CASE WHEN VelocityCategory = 'Hot' THEN 1 ELSE 0 END) as 'Hot SKUs',
SUM(CASE WHEN VelocityCategory = 'Hot' THEN SALES ELSE 0 END) as 'Hot Picks',
SUM(CASE WHEN VelocityCategory = 'Warm' THEN 1 ELSE 0 END) as 'Warm SKUs',
SUM(CASE WHEN VelocityCategory = 'Warm' THEN SALES ELSE 0 END) as 'Warm Picks',
SUM(CASE WHEN VelocityCategory = 'Cold' THEN 1 ELSE 0 END) as 'Cold SKUs',
SUM(CASE WHEN VelocityCategory = 'Cold' THEN SALES ELSE 0 END) as 'Cold Picks'
FROM [dbo].[VelocityBase] Base
LEFT OUTER JOIN [dbo].[VelocitySalesCount] SalesCount
ON Base.ItemId = SalesCount.ItemId
AND Base.ConfigId = SalesCount.ConfigId
AND Base.InventSizeId = SalesCount.InventSizeId
AND Base.InventColorId = SalesCount.InventColorId
AND Base.InventLocationId = SalesCount.InventLocationId
AND SalesCount.DataAreaId = Base.DataAreaId
GROUP BY Aisle
ORDER BY Aisle
但是,這些列是硬編碼的。 我想要的是根據數據庫中該列中存在的值來生成“熱”,“暖”,“冷”等。 這樣,如果用戶添加了以“ Lukewarm”作為行速類別的行,則該數據將出現兩個新列。
我不確定是否可以使用類似SQL的方法來生成SQL或PIVOT函數。
提前致謝!
編輯:
我正在縮小范圍。使用以下方法可以得出“銷售總額”數據:
DECLARE @SQLStatement NVARCHAR(4000)
,@PivotValues NVARCHAR(4000);
SET @PivotValues = '';
SELECT @PivotValues = @PivotValues + ',' + QUOTENAME(VelocityCategory)
FROM
(
SELECT DISTINCT VelocityCategory
FROM dbo.VelocityBase
) src;
SET @PivotValues = SUBSTRING(@PivotValues,2,4000);
SELECT @SQLStatement =
'SELECT pvt.*
FROM
(
SELECT Aisle, VelocityCategory, Sales
FROM VelocityBase Base
LEFT OUTER JOIN [dbo].[VelocitySalesCount] SalesCount
ON Base.ItemId = SalesCount.ItemId
AND Base.ConfigId = SalesCount.ConfigId
AND Base.InventSizeId = SalesCount.InventSizeId
AND Base.InventColorId = SalesCount.InventColorId
AND Base.InventLocationId = SalesCount.InventLocationId
AND SalesCount.DataAreaId = Base.DataAreaId
) VelocityBase
PIVOT ( Sum(Sales) FOR VelocityCategory IN ('+@PivotValues+') ) pvt';
EXECUTE sp_executesql @SQLStatement;
感謝您到上一個問題的鏈接,這使我到現在為止。
我通常不使用PIVOT,而只是使用“通常”的動態SQL,如下所示:
DECLARE @sSQL NVARCHAR(MAX)= '' ,
@sSQLSum NVARCHAR(MAX)= '' ,
@sSQlBegin NVARCHAR(MAX)= '
SELECT Aisle, COUNT(*) As ''# SKUs'',
SUM(Sales) As ''# Picks'',
' ,
@sSQLEnd NVARCHAR(MAX)= 'FROM [Dbo].[VelocityBase] Base
LEFT OUTER JOIN [Dbo].[VelocitySalesCount] SalesCount
ON Base.ItemId = SalesCount.ItemId
AND Base.ConfigId = SalesCount.ConfigId
AND Base.InventSizeId = SalesCount.InventSizeId
AND Base.InventColorId = SalesCount.InventColorId
AND Base.InventLocationId = SalesCount.InventLocationId
AND SalesCount.DataAreaId = Base.DataAreaId
GROUP BY Aisle
ORDER BY Aisle' ;
WITH c AS ( SELECT DISTINCT
VelocityCategory N
FROM Dbo.VelocityBase
)
SELECT @sSQLSum = @sSQLSum + 'SUM(CASE WHEN c.N=''' + c.N
+ ''' THEN 1 ELSE 0 END ) AS ''' + c.N + ' SKUs'',' + CHAR(13)
+ 'SUM(CASE WHEN c.N=''' + c.N
+ ''' THEN SALES ELSE 0 END ) AS ''' + c.N + ' Sales'',' + CHAR(13)
FROM c
IF(LEN(@sSQLSum))>0
SET @sSQLSum = LEFT(@sSQLSum, ( LEN(@sSQLsum) - 2 ))
SET @sSQL = @sSQlBegin + @sSQLSum + CHAR(13) + @sSQLEnd
EXEC (@sSQL)
除非您動態生成查詢,否則我認為沒有一種生成所需內容的方法。
如果您的表已標准化,則可以輕松解決您的問題。 例如, VelocityBase
表應具有VelocityCategoryID
列而不是VelocityCategory
列。 此新列應該是名為VelocityCategory
(或類似名稱)的新表的foreign key
,因此您對此計算的查詢幾乎變得無關緊要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.