我有两个表格,结构如下:
过道| ItemId |配置| InventSizeId | InventColorId | InventLocationId | DataAreaId | VelocityCategory
ItemId |配置| InventSizeId | InventColorId | InventLocationId | DataAreaId |销售
Base表中的每一行代表一个SKU,相关SalesCount记录“Sales”字段的总和决定了“Picks”。此查询有效:
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”作为VelocityCategory的行,则会出现两个带有该数据的新列。
我不确定生成SQL或者PIVOT函数之类的SQL是否可以解决问题。
提前致谢!
编辑:
我正在缩小范围。我用这个得到了销售总和数字:
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;
感谢前一个问题的链接让我走到了这一步。
答案 0 :(得分:1)
我通常不使用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)
答案 1 :(得分:0)
除非您动态生成查询,否则我认为没有办法生成您想要的内容。
如果您的表格已正常化,您的问题可以轻松解决。例如,VelocityBase
表应该有VelocityCategoryID
列,而不是VelocityCategory
列。这个新列应该是foreign key
到一个名为VelocityCategory
的新表(或类似的东西),那么您对此计算的查询几乎是微不足道的。