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

但我希望列出任何类的每个 List 值。

而不是通过编写充满 CASE 的 SQL 查询来寻找替代方案,例如 CASE Member WHEN 'm1' then Value, CASE Member WHEN 'm2' then Value, ... 为了实现我想要的,我想知道是否有机会使用进行一些调整以使其适合我的任务?

数据库是 SQL 2008 R2

谢谢

4

2 回答 2

2

No.是围绕表达式PIVOT进行聚合的有效语法糖。CASE如果糖不起作用,你需要回到较长的形式。

子句PIVOT中完整描述了for 的语法: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值只有一行m1and m2

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有多行,并且您只想说它们的值,那么您将在我上面的查询子查询中创建and :m1m2MAXm1m2

...
    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 回答