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

SQLで列と行を転置する簡単な方法は?

    このデータを変換する方法はいくつかあります。元の投稿で、PIVOT このシナリオには複雑すぎるように見えますが、UNPIVOTの両方を使用して非常に簡単に適用できます。 およびPIVOT SQLServerの関数。

    ただし、これらの機能にアクセスできない場合は、UNION ALLを使用して複製できます。 UNPIVOTへ 次に、CASEを使用した集計関数 PIVOTへのステートメント :

    テーブルの作成:

    CREATE TABLE yourTable([color] varchar(5), [Paul] int, [John] int, [Tim] int, [Eric] int);
    
    INSERT INTO yourTable
        ([color], [Paul], [John], [Tim], [Eric])
    VALUES
        ('Red', 1, 5, 1, 3),
        ('Green', 8, 4, 3, 5),
        ('Blue', 2, 2, 9, 1);
    

    Union All、Aggregate、CASEバージョン:

    select name,
      sum(case when color = 'Red' then value else 0 end) Red,
      sum(case when color = 'Green' then value else 0 end) Green,
      sum(case when color = 'Blue' then value else 0 end) Blue
    from
    (
      select color, Paul value, 'Paul' name
      from yourTable
      union all
      select color, John value, 'John' name
      from yourTable
      union all
      select color, Tim value, 'Tim' name
      from yourTable
      union all
      select color, Eric value, 'Eric' name
      from yourTable
    ) src
    group by name
    

    SQL Fiddle with Demo

    を参照してください

    UNION ALL UNPIVOTを実行します 列を変換してデータを抽出するPaul, John, Tim, Eric 別々の行に。次に、集計関数sum()を適用します caseで 各colorの新しい列を取得するステートメント 。

    Unpivot and Pivot Static Version:

    両方のUNPIVOT およびPIVOT SQL Serverの関数を使用すると、この変換がはるかに簡単になります。変換する値がすべてわかっている場合は、それらを静的バージョンにハードコーディングして結果を得ることができます。

    select name, [Red], [Green], [Blue]
    from
    (
      select color, name, value
      from yourtable
      unpivot
      (
        value for name in (Paul, John, Tim, Eric)
      ) unpiv
    ) src
    pivot
    (
      sum(value)
      for color in ([Red], [Green], [Blue])
    ) piv
    

    SQL Fiddle with Demo

    を参照してください

    UNPIVOTを使用した内部クエリ UNION ALLと同じ機能を実行します 。列のリストを取得して行に変換します。PIVOT 次に、列への最終変換を実行します。

    ダイナミックピボットバージョン:

    列の数が不明な場合(Paul, John, Tim, Eric あなたの例では)そして変換する色の数が不明な場合は、動的SQLを使用してUNPIVOTのリストを生成できます 次にPIVOT

    DECLARE @colsUnpivot AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX),
        @colsPivot as  NVARCHAR(MAX)
    
    select @colsUnpivot = stuff((select ','+quotename(C.name)
             from sys.columns as C
             where C.object_id = object_id('yourtable') and
                   C.name <> 'color'
             for xml path('')), 1, 1, '')
    
    select @colsPivot = STUFF((SELECT  ',' 
                          + quotename(color)
                        from yourtable t
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    
    set @query 
      = 'select name, '[email protected]+'
          from
          (
            select color, name, value
            from yourtable
            unpivot
            (
              value for name in ('[email protected]+')
            ) unpiv
          ) src
          pivot
          (
            sum(value)
            for color in ('[email protected]+')
          ) piv'
    
    exec(@query)
    

    SQL Fiddle with Demo

    を参照してください

    動的バージョンは、両方のyourtableにクエリを実行します 次に、sys.columns UNPIVOTへのアイテムのリストを生成するためのテーブル およびPIVOT 。次に、これが実行されるクエリ文字列に追加されます。動的バージョンの利点は、colorsの変更リストがある場合です。 および/またはnames これにより、実行時にリストが生成されます。

    3つのクエリすべてで同じ結果が生成されます:

    | NAME | RED | GREEN | BLUE |
    -----------------------------
    | Eric |   3 |     5 |    1 |
    | John |   5 |     4 |    2 |
    | Paul |   1 |     8 |    2 |
    |  Tim |   1 |     3 |    9 |
    


    1. Windows用の良いpostgresqlクライアント?

    2. androidのSqliteからのListView

    3. 長いバイナリ(生データ)文字列の保存

    4. CAST()を使用してSQLServerで日付形式を変換する方法