sql >> データベース >  >> RDS >> Sqlserver

動的ピボットの行と列の合計

    サンプルテーブル

    SELECT * INTO #tblStock
    FROM
    (
    SELECT 'A' PartCode,  10 StockQty, 'WHs-A' Location
    UNION ALL
    SELECT 'B',   22,  'WHs-A'
    UNION ALL
    SELECT 'A',   1,   'WHs-B'
    UNION ALL
    SELECT 'C',   20,  'WHs-A'
    UNION ALL
    SELECT 'D',   39,  'WHs-F'
    UNION ALL
    SELECT 'E',   3,   'WHs-D'
    UNION ALL
    SELECT 'F',   7,   'WHs-A'
    UNION ALL
    SELECT 'A',   9,   'WHs-C'
    UNION ALL
    SELECT 'D',   2,   'WHs-A'
    UNION ALL
    SELECT 'F',   54,  'WHs-E'
    )TAB
    

    動的ピボットの列を取得し、NULLを置き換えます zero

    DECLARE @cols NVARCHAR (MAX)
    
    SELECT @cols = COALESCE (@cols + ',[' + Location + ']', '[' + Location + ']')
                   FROM (SELECT DISTINCT Location FROM #tblStock) PV 
                   ORDER BY Location 
    -- Since we need Total in last column, we append it at last
    SELECT @cols += ',[Total]'
    
    
    --Varible to replace NULL with zero
    DECLARE @NulltoZeroCols NVARCHAR (MAX)
    
    SELECT @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+Location+'],0) AS ['+Location+']' 
    FROM (SELECT DISTINCT Location FROM #tblStock)TAB  
    ORDER BY Location FOR XML PATH('')),2,8000) 
    
    SELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
    

    CUBEを使用できます 行と列の合計を検索し、NULLを置き換えます Total CUBEから生成された行の場合 。

    DECLARE @query NVARCHAR(MAX)
    SET @query = 'SELECT PartCode,' + @NulltoZeroCols + ' FROM 
                 (
                     SELECT 
                     ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode, 
                     SUM(StockQty)StockQty , 
                     ISNULL(Location,''Total'')Location              
                     FROM #tblStock
                     GROUP BY Location,PartCode
                     WITH CUBE
                 ) x
                 PIVOT 
                 (
                     MIN(StockQty)
                     FOR Location IN (' + @cols + ')
                ) p
                ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode' 
    
    EXEC SP_EXECUTESQL @query
    

    結果

    注:NULLが必要な場合 zeroの代わりに 値として、@colsを使用します @NulltoZeroColsの代わりに 動的ピボットコードで

    編集:

    1。行の合計のみを表示

    • コードを使用しないでくださいSELECT @cols += ',[Total]' およびSELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
    • ROLLUPを使用する CUBEの代わりに 。

    2。列の合計のみを表示

    • コードを使用SELECT @cols += ',[Total]' およびSELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
    • ROLLUPを使用する CUBEの代わりに 。
    • GROUP BY Location,PartCodeを変更します GROUP BY PartCode,Locationへ 。
    • ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCodeの代わりに 、WHERE PartCode<>''TOTAL'' ORDER BY PartCodeを使用します 。

    更新:PartNameを提供する OPの場合

    以下のクエリを更新して、PartNameを追加します 結果で。 PartName以降 CUBEで結果を追加します ANDの混乱を避けるため またはOR 条件、ピボットされた結果をDISTINCTと結合することをお勧めします ソーステーブルの値。

    DECLARE @query NVARCHAR(MAX)
    SET @query = 'SELECT P.PartCode,T.PartName,' + @NulltoZeroCols + ' FROM 
                 (                
                     SELECT 
                     ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode, 
                     SUM(StockQty)StockQty , 
                     ISNULL(Location,''Total'')Location              
                     FROM #tblStock
                     GROUP BY Location,PartCode
                     WITH CUBE                   
                 ) x
                 PIVOT 
                 (
                     MIN(StockQty)
                     FOR Location IN (' + @cols + ')
                ) p
                LEFT JOIN
                (  
                    SELECT DISTINCT PartCode,PartName
                    FROM #tblStock  
                )T
                ON P.PartCode=T.PartCode
                ORDER BY CASE WHEN (P.PartCode=''Total'') THEN 1 ELSE 0 END,P.PartCode' 
    
    EXEC SP_EXECUTESQL @query
    



    1. JSONデータに対するSQLのようなクエリを可能にするJavascriptライブラリ?

    2. 重複キー更新のMySQL+影響を受ける行数

    3. 古いレコードを削除して新しいレコードを挿入するMySQLトリガー

    4. Ruby On Railsは遅い...?