1

こんにちは、次のデータの表があります

Class | Member | Value
----------------------
c1    | m1     | 10
c1    | m2     | 20
c1    | list   | 30
c1    | list   | 40
c1    | list   | 50
c2    | m1     | 60
c2    | m2     | 70
c2    | list   | 80

データをこのフォームにピボットしたい

Class | Member 1 | Member 2 | List
----------------------------------
c1    | 10       | 20       | 30
c1    | 10       | 20       | 40
c1    | 10       | 20       | 50
c2    | 60       | 70       | 80

集約関数として max を使用する通常のピボットでは、

Class | Member 1 | Member 2 | List
----------------------------------
c1    | 10       | 20       | 50
c2    | 60       | 70       | 80

しかし、私は任意のクラスのリスト値のそれぞれを一覧表示したいと考えています。

CASE Member WHEN 'm1' then Value、CASE Member WHEN 'm2' then Value など、CASE でいっぱいの SQL クエリを記述して代替手段を見つけるのではなく、目的を達成するために、使用する機会があるかどうかを知りたい私の仕事のためにそれを機能させるためにいくつかの調整を加えてピボットしますか?

データベースは SQL 2008 R2 です

ありがとうございました

4

2 に答える 2

2

No.PIVOTは、式の周りで集計を行うための効果的な構文糖衣ですCASE。砂糖が効かない場合は、長い形に戻る必要があります.

の構文は、句PIVOTで完全に説明されています。FROM

<pivoted_table> ::=
    table_source PIVOT <pivot_clause> [ AS ] table_alias

<pivot_clause> ::=
        ( aggregate_function ( value_column [ [ , ]...n ]) 
        FOR pivot_column 
        IN ( <column_list> ) 
    ) 

また、指定する必要があることに注意してaggregate_functionください。SQL Server のすべての集計関数は、任意の数の入力値に対して動作し、単一の出力値を生成します。ここで必要になるように、複数の出力値を生成できる集計はありません。


これにより、要求した結果が得られますが、各値がとClassのそれぞれに対して 1 つの行しかないことに依存しています。m1m2

declare @t table (Class char(2) not null,Member varchar(4) not null,Value int not null)
insert into @t(Class,Member,Value) values
('c1','m1',10),
('c1','m2',20),
('c1','list',30),
('c1','list',40),
('c1','list',50),
('c2','m1',60),
('c2','m2',70),
('c2','list',80)

select l.Class,m1.Value as m1,m2.Value as m2,l.Value as list
from
    @t l
        inner join
    @t m1
        on
            l.Class = m1.Class and
            m1.Member = 'm1'
        inner join
    @t m2
        on
            l.Class = m2.Class and
            m2.Member = 'm2'where
l.Member='list'

結果:

Class m1          m2          list
----- ----------- ----------- -----------
c1    10          20          30
c1    10          20          40
c1    10          20          50
c2    60          70          80

andに複数の行がありm1m2たとえばMAXそれらの値が必要な場合は、上記のクエリ サブクエリでm1andを作成します。m2

...
    inner join
(select Class,MAX(Value) from @t where Member='m1' group by Class) m1
    on
        l.Class = m1.Class
...
于 2013-01-24T07:35:03.727 に答える
1
SELECT  a.*, 
        b.Value
FROM    
        (
            SELECT  Class,
                    MAX(CASE WHEN Member = 'm1' THEN Value ELSE NULL END) [Member 1],
                    MAX(CASE WHEN Member = 'm2' THEN Value ELSE NULL END) [Member 2]
            FROM  tableName
            GROUP BY Class
        ) a 
        INNER JOIN
        (
            SELECT  Class, Value
            FROM    tableName 
            WHERE   Member = 'List'
        ) b ON a.Class = b.Class

結果

╔═══════╦══════════╦══════════╦═══════╗
║ CLASS ║ MEMBER 1 ║ MEMBER 2 ║ VALUE ║
╠═══════╬══════════╬══════════╬═══════╣
║ c1    ║       10 ║       20 ║    30 ║
║ c1    ║       10 ║       20 ║    40 ║
║ c1    ║       10 ║       20 ║    50 ║
║ c2    ║       60 ║       70 ║    80 ║
╚═══════╩══════════╩══════════╩═══════╝
于 2013-01-24T07:31:44.663 に答える