透视多行

时间:2012-03-23 20:32:27

标签: sql-server sql-server-2005

我有一张类似于以下内容的表格:

id    key    str_val    date_val      num_val
1     A      a
1     B      b
1     C                 2012-01-01
1     D                               1
2     A      c
2     E      d
2     C                 2012-01-02
2     D                                2

我需要它看起来像:

id    A      B      C             D       E
1     a      b      2012-01-01    1
2     c             2012-01-02    2       d

基本上,每个密钥都需要成为它自己的列

我尝试过并且无法有效地使用PIVOT命令,而我正在尝试使用case语句来完成此操作。即。

select
    id,
    case key
        when 'A'
        then str_val
    end as A,
    case key
        when 'C'
        then date_val
    end as C
    --etc.
from test_table

但是我无法弄清楚如何在运行后组合表行。我坚持:

id    A      B      C             D       E
1     a
1            b
1                   2012-01-01
1                                 1

任何可以帮助我的想法或输入?提前谢谢。

2 个答案:

答案 0 :(得分:3)

你有90%的路在那里:

with cte as (
    select 
        id, 
        case [key] 
            when 'A' 
            then str_val 
        end as A, 
        case [key] 
            when 'B' 
            then str_val 
        end as B, 
        case [key] 
            when 'C' 
            then date_val 
        end as C, 
        case [key] 
            when 'D' 
            then num_val 
        end as D,
        case [key] 
            when 'E' 
            then str_val 
        end as E 
    from test_table
)
select id, max(A) as A, max(B) as B, max(C) as C, max(D) as D, max(E) as E
from cte
group by id

答案 1 :(得分:2)

只要id和key是每个表的唯一组合,那么您可以编写如下查询:

SELECT ta.str_val as A,
       tb.str_val as B,
       tc.date_val as C,
       td.num_val as D,
       te.str_val as E
FROM (SELECT DISTINCT id FROM test_table) ids
LEFT JOIN test_table ta ON ids.id = ta.id AND ta.key = 'A'
LEFT JOIN test_table tb ON ids.id = tb.id AND tb.key = 'B'
LEFT JOIN test_table tc ON ids.id = tc.id AND tc.key = 'C'
LEFT JOIN test_table td ON ids.id = td.id AND td.key = 'D'
LEFT JOIN test_table tc ON ids.id = te.id AND te.key = 'E';

在此查询中,您将获得所有ID(如果您可以回复“A”列,那么您可以从那里开始)。然后你必须加入给定id的每个键。

如果您不能依赖密钥的数据类型,即A可能是字符串或日期,那么您必须为每个选择使用以下内容:

COALESCE(ta.str_val,TO_CHAR(ta.date_val,'DD-MM-YYYY'),TO_CHAR(ta.num_val)) A,
COALESCE(tb.str_val,TO_CHAR(tb.date_val,'DD-MM-YYYY'),TO_CHAR(tb.num_val)) B,
...
etc.