2

すぐに飛び込みましょう。これがコードです

SELECT [prov], [201304], [201305], [201306], [201307]
FROM (
SELECT [prov], [arrival], [Amount]
FROM [tblSource]) up
PIVOT (SUM([Amount]) FOR [arrival] IN ([201304], [201305], [201306], [201307])) AS pvt
GO

とても素敵なテーブルに戻ります。各「日付」列の合計を追加された最後の行に表示する方法を知りたいと思っていましたか?

さらに、基になるテーブルには、より多くのデータ、具体的にはより多くの日付が追加されます。これは、201308が次に追加され、次に201309などが追加されることを意味します。

これは、現在、追加を反映するために毎月上記のコードを修正する必要があることを意味します。とにかくこのあたりはありますか?

4

2 に答える 2

2

動的 SQL を使用して列を動的に作成できますが、SSRS や Excel など、動的ピボット用に設計されたレイヤーで動的ピボットを処理することを強くお勧めします。

DECLARE @SQL NVARCHAR(MAX) = '',
        @SQL2 NVARCHAR(MAX) = '',
        @SQL3 NVARCHAR(MAX) = '';

-- COMPILE THE UNIQUE VALUES FOR ARRIVAL THAT NEED TO BE PIVOTED
SELECT  @SQL = @SQL + ',' + QUOTENAME(Arrival),
        @SQL2 = @SQL2 + '+ISNULL(' + QUOTENAME(Arrival) + ', 0)',
        @SQL3 = @SQL3 + ',' + QUOTENAME(Arrival) + ' = ISNULL(' + QUOTENAME(Arrival) + ', 0)'
FROM    (SELECT DISTINCT Arrival FROM tblSource) s;

-- COMBINE THEM INTO A SINGLE QUERY
SET @SQL = 'SELECT [Prov]' + @SQL3 + ', [Total] = ' + STUFF(@SQL2, 1, 1, '') + '
            FROM    (   SELECT  Arrival, Prov, Amount
                        FROM    [tblSource]
                        UNION ALL
                        SELECT  Arrival, ''Total'', SUM(Amount)
                        FROM    [tblSource]
                        GROUP BY Arrival
                    ) up
                    PIVOT
                    (   SUM(Amount)
                        FOR Arrival IN (' + STUFF(@SQL, 1, 1, '') + ')
                    ) pvt;';

-- EXECUTE THE QUERY
EXECUTE SP_EXECUTESQL @SQL;

これにより、次の SQL が作成されて実行されます。

SELECT  [Prov],
        [2013-01-01] = ISNULL([2013-01-01], 0),
        [2013-02-01] = ISNULL([2013-02-01], 0), 
        [Total] = ISNULL([2013-01-01], 0) + ISNULL([2013-02-01], 0)
FROM    (   SELECT  Arrival, Prov, Amount
            FROM    [tblSource]
            UNION ALL
            SELECT  Arrival, 'Total', SUM(Amount)
            FROM    [tblSource]
            GROUP BY Arrival
        ) up
        PIVOT
        (   SUM(Amount)
            FOR Arrival IN ([2013-01-01],[2013-02-01])
        ) pvt;

下部に合計行を追加するのは、サブクエリのユニオンの下のクエリupであり、行の合計は、行のすべての列を追加することによって単純に作成されます。

SQL Fiddle の例

もう一度強調しますが、SQL の外部でこのようなデータ操作を処理することを強くお勧めします。

編集

UNION を使用して合計行を取得する代わりに、GROUPING SETS次のように使用することもできます。

DECLARE @SQL NVARCHAR(MAX) = '',
        @SQL2 NVARCHAR(MAX) = '',
        @SQL3 NVARCHAR(MAX) = '';

-- COMPILE THE UNIQUE VALUES FOR ARRIVAL THAT NEED TO BE PIVOTED
SELECT  @SQL = @SQL + ',' + QUOTENAME(Arrival),
        @SQL2 = @SQL2 + '+ISNULL(' + QUOTENAME(Arrival) + ', 0)',
        @SQL3 = @SQL3 + ',' + QUOTENAME(Arrival) + ' = ISNULL(' + QUOTENAME(Arrival) + ', 0)'
FROM    (SELECT DISTINCT Arrival FROM tblSource) s;

-- COMBINE THEM INTO A SINGLE QUERY
SET @SQL = 'SELECT [Prov]' + @SQL3 + ', [Total] = ' + STUFF(@SQL2, 1, 1, '') + '
            FROM    (   SELECT  Arrival, Prov = ISNULL(Prov, 'Total'), Amount = SUM(Amount)
                        FROM    [tblSource]
                        GROUP BY GROUPING SETS((Prov, arrival), (arrival))
                    ) up
                    PIVOT
                    (   SUM(Amount)
                        FOR Arrival IN (' + STUFF(@SQL, 1, 1, '') + ')
                    ) pvt;';

-- EXECUTE THE QUERY
EXECUTE SP_EXECUTESQL @SQL;
于 2013-08-06T13:35:47.110 に答える