0

日付に基づいてテーブル内のデータをピボットしていますが、データのない日付にはNULLを返す必要があります。

[dbo]。[メトリクス]のデータ:

指標

私が実行している動的ピボットSQL:

DECLARE @cols NVARCHAR(1000);
SELECT @cols = 
STUFF((SELECT N'],[' + month_day
         FROM (SELECT DISTINCT RIGHT(CONVERT(NCHAR(10), [Date], 126), 2)
                 FROM [Metrics]) AS O(month_day)
         ORDER BY month_day
          FOR XML PATH('')
       ), 1, 2, '') + N']';

DECLARE @sql NVARCHAR(2000);

SET @sql =
N'SELECT [Key], ' + @cols +
N'  FROM (SELECT [Key], ' +
N'               RIGHT(CONVERT(NCHAR(10), [Date], 126), 2) AS month_day, ' +
N'               [Value] ' +
N'          FROM [Metrics]) AS O ' +
N'PIVOT ' +
N'(SUM([Value]) FOR month_day IN (' + @cols + N')) AS P;';

EXECUTE(@sql);

...そして動的SQLが返す結果セット:

ピボットデータ

ご覧のとおり、私はその月の毎日のデータを持っていないため、その日の列を返さないだけです。セルごとにNULLの列10-23および28-31を返すようにするにはどうすればよいですか?実際の月に関係なく、列1〜31を返す必要があります(たとえば、特定の月の日数が31日未満の場合でも31列)。

どんな助けでも大歓迎です。

4

1 に答える 1

2

次に、列を動的に生成する必要はありません。常に 1 から 31 までの列が必要だからです。より簡単な方法は、ピボットでこれらの値をハードコーディングすることです。とにかく、列を動的に定義してもすべての日を取得できる方法は次のとおりです。

SELECT @cols = 
STUFF((SELECT N'],[' + CAST(number AS VARCHAR(2))
         FROM (SELECT DISTINCT number
               FROM master..[spt_values] 
               WHERE number BETWEEN 1 AND 31) AS O(number)
         ORDER BY number
          FOR XML PATH('')
       ), 1, 2, '') + N']';

そして、実際に使用する必要があるバージョンは次のとおりです。

SELECT *
FROM (SELECT [Key], 
             RIGHT(CONVERT(NCHAR(10), [Date], 126), 2) AS month_day, 
             [Value] 
      FROM [Metrics]) AS O 
PIVOT (SUM([Value]) FOR month_day IN ([01],[02],[03],[04],[05],[06],[07],[08],[09],
                                      [10],[11],[12],[13],[14],[15],[16],[17],[18],
                                      [19],[20],[21],[22],[23],[24],[25],[26],[27],
                                      [28],[29],[30],[31])) AS P;
于 2013-02-27T19:55:35.587 に答える