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

SQL:動的ピボットで ISNULL を使用する

    列名が変更されているという点で動的ですが、列の数をまだハードコーディングしているため、クエリを少し異なる設定にします。

    まず、再帰 CTE を使用して、作成する月/年のリストを生成します。

    DECLARE @startDate datetimeSET @startDate ='2013-01-01';with days as( select @startdate datelist, 1 sp union all select dateadd(month, 1, datelist), sp+1 from date where sp+1 <=5 -- この数値 5 を必要な月数に変更します)select sp, REPLACE(SUBSTRING(CONVERT(varchar(11), datelist, 13), 4, 8), ' ', '') MONTHANDYEAR日付から  

    SQL Fiddle with Demo を参照してください。 .これにより、年を含む 5 か月のリストが自動的に作成されます。次に、5 つの列をハードコーディングしていません。現在のクエリは、可能な限り柔軟ではありません。その後 12 か月が必要な場合は、コードを変更する必要があります。

    日付のリストを生成したら、それを一時テーブルに挿入して、それを使用して列を取得できるようにします。

    列のリストを取得するコードは次のとおりです:

    select @cols =STUFF((SELECT ',' + QUOTENAME(monthandyear) from #datesTemp group by monthandyear, sp order by sp FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')select @colNames =STUFF((SELECT ', isnull(' + QUOTENAME(monthandyear)+', 0) as '+QUOTENAME(monthandyear) from #datesTemp group by月と年, sp FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')  

    デモによる SQL Fiddle を参照してください。 . 2 つのバージョンがあることがわかります。最初の @cols pivot で使用される列のリストを取得します . 2 番目の @colNames 最後の SELECT で使用されます null を置き換えるリスト ゼロを含む値。

    次に、すべてをまとめると、コードは次のようになります。 -dynamically-pivot-and-group-results">前の質問 )

    DECLARE @cols AS NVARCHAR(MAX), @colNames AS NVARCHAR(MAX), @query AS NVARCHAR(MAX), @startDate datetimeSET @startDate ='2013-01-01';with date as( select @startdate datelist, 1 sp union all select dateadd(month, 1, datelist), sp+1 from date from sp+1 <=5 -- この数値 5 を必要な月数に変更します)select sp, REPLACE(SUBSTRING (CONVERT(varchar(11), datelist, 13), 4, 8), ' ', '') MONTHANDYEARinto #datesTempfromdatesselect @cols =STUFF((SELECT ',' + QUOTENAME(monthandyear) from #datesTemp group by monthandyear, sp FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')select @colNames =STUFF((SELECT ', isnull(' + QUOTENAME(monthandyear)+', 0) as '+QUOTENAME(monthandyear) from #datesTemp group by monthandyear, sp order by sp FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')set @query ='SELECT resource, clientname,' + @colNames + ' from ( select [CLIENTNAME], [RESOURCE], [FORECASTTOTAL], REPLACE(SUBSTRING( CONVERT(varchar(11), SCHEDULEDDATE, 13), 4, 8), '' '', '''') monthandyear from viewprojscheduling_group ) x ピボット ( sum(FORECASTTOTAL) for monthandyear in (' + @cols + ') ) p 'execute(@query)  

    デモによる SQL Fiddle を参照してください。 .このクエリは結果を返します:

    <プレ>|リソース |クライアント名 | 2013年1月 | 2013年2月 | 2013年3月 | 2013年4月 | 2013 年 5 月 |------------------------------------------------ ---------------------------| res1 | abc | 1000 | 2000年 | 0 | 0 | 0 || res1 |デフ | 0 | 0 | 2000年 | 0 | 0 || res2 |デフ | 1500 | 0 | 0 | 0 | 0 || res3 |ギ | 0 | 0 | 2500 | 0 | 0 |


    1. mysqlとangularからデータを削除します

    2. SQLServerで削除されたデータベースを追跡する方法

    3. `having`で`rand()`を使用する

    4. SQL2005ServerからTimeZoneInfoにアクセスします