2

このようなテーブルがあります...

LEVEL        Action         Date             User
--------------------------------------------------
1            Approve        01/01/2013       User1
2            Approve        02/01/2013       User2
3            Rejected       03/01/2013       User3
1            Approve        04/01/2013       User1
2            Approve        05/01/2013       User2
3            Approve        06/01/2013       User3
.                .              .              .
.                .              .              .
.                .              .              .

そしてこれが欲しい…

これはPIVOTを使用して可能ですか?

LEVEL1 - User 1           LEVEL2 - User 2                  LEVEL3 - User 3
---------------------------------------------------------------------------
01/01/2013 - Approve      02/01/2013 - Approve             03/01/2013 - Rejected
04/01/2013 - Approve      05/01/2013 - Approve             06/01/2013 - Approve
         .                        .                                .
         .                        .                                .

注 : レベルの数は動的です。たとえば、1 つのアイテムを完全に承認するには、5 レベル、6 レベルなどがあります。したがって、ピボット テーブルの列数は動的です。

4

1 に答える 1

7

はい、これはPIVOT関数を使用して行うことができます。まず、クエリの動的バージョンに移動する前に、クエリがどのように記述されているかを確認できるように、ハードコードされたバージョンのクエリを確認することをお勧めします。

静的バージョンは次のようになります。

select [Level1 - User1], [Level2 - User2], [Level3 - User3]
from
(
  select 'Level'+cast(level as varchar(1)) + ' - '+ [user] col, 
    convert(varchar(10), date, 101) +' - '+ action value,
    row_number() over(partition by level order by [user], date) rn
  from yt
) d
pivot
(
  max(value)
  for col in ([Level1 - User1], [Level2 - User2], [Level3 - User3])
) piv;

SQL Fiddle with Demoを参照してください。と のleveluserが連結されて新しい列が作成され、dateactionが連結されて各列の値が作成されます。row_number()また、各行に一意の値を作成するために を追加しました。これは、PIVOT で集計関数を適用するときに重要になります。これを使用しない場合、結果として 1 行しか得られません。

これで作業バージョンができたので、これを動的バージョンに簡単に変換できます。

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Level'+cast(level as varchar(1)) + ' - '+ [user]) 
                    from yt
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ' + @cols + ' from 
             (
                select ''Level''+cast(level as varchar(1)) + '' - ''+ [user] col, 
                  convert(varchar(10), date, 101) +'' - ''+ action value,
                  row_number() over(partition by level order by [user], date) rn
                from yt
            ) x
            pivot 
            (
                max(value)
                for col in (' + @cols + ')
            ) p '

execute(@query);

SQL Fiddle with Demoを参照してください。両方の結果は次のとおりです。

|       LEVEL1 - USER1 |       LEVEL2 - USER2 |        LEVEL3 - USER3 |
-----------------------------------------------------------------------
| 01/01/2013 - Approve | 02/01/2013 - Approve | 03/01/2013 - Rejected |
| 04/01/2013 - Approve | 05/01/2013 - Approve |  06/01/2013 - Approve |
于 2013-05-07T11:28:13.897 に答える