2013-09-25 47 views
0

我的情况,我需要本数据更改为所需的一个。转换多列到一行

下面是数据

ColumnA ColumnB ColumnC 
     P  Q  R 
     S  T  U 
     V  W  X 

要求的格式是

ColumnA1 ColumnB1 ColumnC1 ColumnA2 ColumnB2 ColumnC2 ColumnA3 ColumnB3 ColumnC3  
    P   Q   R  S  T   U   V  W  x 

请帮我在这。

+0

询问代码的问题必须证明对所解决问题的最小理解。包括尝试解决方案,为什么他们没有工作,以及预期的结果。的[加入与行的表] – Kermit

+0

可能重复(http://stackoverflow.com/questions/13583028/join-tables-with-rows) –

回答

1

有几个方法,你可以得到的结果全部涉及使用row_number来生成数据的每一行的序列。

可以使用聚合函数CASE表达式:

select 
    max(case when seq = 1 then columna end) columna_1, 
    max(case when seq = 1 then columnb end) columnb_1, 
    max(case when seq = 1 then columnc end) columnc_1, 
    max(case when seq = 2 then columna end) columna_2, 
    max(case when seq = 2 then columnb end) columnb_2, 
    max(case when seq = 2 then columnc end) columnc_2, 
    max(case when seq = 3 then columna end) columna_3, 
    max(case when seq = 3 then columnb end) columnb_3, 
    max(case when seq = 3 then columnc end) columnc_3 
from 
(
    select columna, columnb, columnc, 
    row_number() over(order by columna) seq 
    from yourtable 
) d; 

SQL Fiddle with Demo

可以使用旋转功能,但你会想先逆转置数据的3列,然后应用PIVOT。 unpivot进程将3列数据转换为多行。您可以使用UNPIVOT功能或CROSS APPLY来执行此:

select ColumnA_1, ColumnB_1, ColumnC_1, 
    ColumnA_2, ColumnB_2, ColumnC_2, 
    ColumnA_3, ColumnB_3, ColumnC_3 
from 
(
    select col = col+'_'+cast(seq as varchar(10)), 
    value 
    from 
    (
    select columna, columnb, columnc, 
     row_number() over(order by columna) seq 
    from yourtable 
) d 
    cross apply 
    (
    select 'ColumnA', columna union all 
    select 'ColumnB', columnb union all 
    select 'ColumnC', columnc 
) c (col, value) 
) s 
pivot 
(
    max(value) 
    for col in (ColumnA_1, ColumnB_1, ColumnC_1, 
       ColumnA_2, ColumnB_2, ColumnC_2, 
       ColumnA_3, ColumnB_3, ColumnC_3) 
) piv; 

SQL Fiddle with Demo。上述两个版本的工作,巨大的,如果你有一个有限数量的或已知值,但如果你将有一个未知号码,那么你将要看看使用动态SQL来得到最终结果:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT ',' + QUOTENAME(col+'_'+cast(seq as varchar(10))) 
        from 
        (
         select row_number() over(order by columna) seq 
         from yourtable 
        ) d 
        cross apply 
        (
         select 'ColumnA', 1 union all 
         select 'ColumnB', 2 union all 
         select 'ColumnC', 3 
        ) c (col, so) 
        group by col, seq, so 
        order by seq, so 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 


set @query = 'SELECT ' + @cols + ' 
      from 
      (
       select col = col+''_''+cast(seq as varchar(10)), 
       value 
       from 
       (
       select columna, columnb, columnc, 
        row_number() over(order by columna) seq 
       from yourtable 
      ) d 
       cross apply 
       (
       select ''ColumnA'', columna union all 
       select ''ColumnB'', columnb union all 
       select ''ColumnC'', columnc 
      ) c (col, value) 
      ) x 
      pivot 
      (
       max(value) 
       for col in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 

SQL Fiddle with Demo 。所有版本将给出结果:

| COLUMNA_1 | COLUMNB_1 | COLUMNC_1 | COLUMNA_2 | COLUMNB_2 | COLUMNC_2 | COLUMNA_3 | COLUMNB_3 | COLUMNC_3 | 
|   P |   Q |   R |   S |   T |   U |   V |   W |   X |