簡體   English   中英

動態多列SQL

[英]Dynamic Multi-Column SQL

我有兩個具有如下結構的表:

VelocityBase

過道| ItemId | ConfigId | InventSizeId | InventColorId | InventLocationId | DataAreaId | VelocityCategory

VelocitySalesCount

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM