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

集計なしの SQL Server 2012 PIVOT

    データを変換する方法はいくつかあります。集計関数を使用するものと使用しないものがあります。ただし、文字列をピボットしても、集計を適用できます。

    CASE で集計:

    select name,
      max(case when category = 'A' then 'X' else '' end) CategoryA,
      max(case when category = 'B' then 'X' else '' end) CategoryB,
      max(case when category = 'C' then 'X' else '' end) CategoryC,
      max(case when category = 'D' then 'X' else '' end) CategoryD
    from yourtable 
    group by name
     

    デモによる SQL Fiddle を参照してください。

    静的ピボット:

    PIVOT は引き続き使用できます 値が文字列であってもデータを変換する関数。既知の数のカテゴリがある場合は、クエリをハードコードできます:

    select name, 
      coalesce(A, '') CategoryA, 
      coalesce(B, '') CategoryB, 
      coalesce(C, '') CategoryC, 
      coalesce(C, '') CategoryD
    from
    (
      select name, category, 'X' flag
      from yourtable
    ) d
    pivot
    (
      max(flag)
      for category in (A, B, C, D)
    ) piv
     

    デモによる SQL Fiddle を参照してください。 .

    動的ピボット:

    カテゴリの数が不明な場合は、動的 SQL を使用できます:

    DECLARE @cols AS NVARCHAR(MAX),
        @colsNull AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT  ',' + QUOTENAME(category) 
                        from yourtable
                        group by category
                        order by category
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    select @colsNull = STUFF((SELECT  ', coalesce(' + QUOTENAME(category)+', '''') as '+QUOTENAME('Category'+category)
                        from yourtable
                        group by category
                        order by category
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    
    set @query = 'SELECT name, ' + @colsNull + ' 
                  from 
                 (
                    select name, category, ''X'' flag
                    from yourtable
                ) x
                pivot 
                (
                    max(flag)
                    for category in (' + @cols + ')
                ) p '
    
    execute(@query)
     

    デモによる SQL Fiddle を参照してください。 .

    複数参加:

    select c1.name,
      case when c1.category is not null then 'X' else '' end as CategoryA,
      case when c2.category is not null then 'X' else '' end as CategoryB,
      case when c3.category is not null then 'X' else '' end as CategoryC,
      case when c4.category is not null then 'X' else '' end as CategoryD
    from yourtable c1
    left join yourtable c2
      on c1.name = c2.name
      and c2.category = 'B'
    left join yourtable c3
      on c1.name = c3.name
      and c3.category = 'C'
    left join yourtable c4
      on c1.name = c4.name
      and c4.category = 'D'
    where c1.category = 'A'
     

    SQL Fiddle with Demo を参照してください。

    すべてのクエリで結果が得られます:

    <プレ>| NAME | CATEGORYA | CATEGORYB | CATEGORYC | CATEGORYD | -------------------------------------------------------- | Joe | X | X | | X | | Mary | X | | X | X |


    1. SQL Serverシステムメッセージから戻り値を取得するにはどうすればよいですか?

    2. CreateSQLQueryは機能しますが、QueryOverはNHibernateでは機能しません

    3. コマンドラインからLinux上のMySQLデータベースを選択する

    4. ORA-29024:証明書の検証に失敗しました