将列值转换为行SQL

时间:2017-04-27 10:24:50

标签: sql sql-server-2008

我有下表显示项目负责人(Res _):

ID NUMBER    BK no_    Res 
LUC00003     BK001     CLARETH
LUC00003     BK001     MARC
LUC00009     BK001     CLARETH
LUC00009    BK001      MICHAEL

我想在行中显示Res_而不是列,以便为每个ID显示一行,如下所示:

ID NUMBER    BK no_    Res 1     Res2
LUC00003     BK001     CLARETH   MARC
LUC00009     BK001     CLARETH   MICHAEL

下面的查询:

SELECT 
  C.[ID NUMBER], 
  CA.[BK No_],
  B.[Res] 
FROM [IDList] C
LEFT JOIN [BK list]  CA ON C.[ID NUMBER] = CA.[ID NUMBER]
LEFT JOIN [Res List] B ON B.[ID NUMBER]= C.[ID NUMBER] AND B.[BK No_]=CA.[BK No_]

1 个答案:

答案 0 :(得分:1)

使用条件聚合:

select 
    id_number
  , bk_no
  , Res1 = max(case when rn = 1 then Res end)
  , Res2 = max(case when rn = 2 then Res end)
from (
  select *
    , rn = row_number() over (partition by id_number, bk_no order by res)
  from t
) sub
group by id_number, bk_no

rextester演示:http://rextester.com/DFCC86645

返回:

+-----------+-------+---------+---------+
| id_number | bk_no |  Res1   |  Res2   |
+-----------+-------+---------+---------+
| LUC00003  | BK001 | CLARETH | MARC    |
| LUC00009  | BK001 | CLARETH | MICHAEL |
+-----------+-------+---------+---------+

动态pivot()版本:

declare @cols nvarchar(max);
declare @sql  nvarchar(max);

  select @cols = stuff((
    select distinct 
      ',' + quotename('Res'
          +convert(varchar(10),row_number() over (
              partition by id_number, bk_no 
              order by     res 
          ))
          )
      from t 
      for xml path (''), type).value('.','nvarchar(max)')
    ,1,1,'');

select @sql = '
 select id_number, bk_no, ' + @cols + '
  from  (
    select 
        id_number
      , bk_no
      , Res
      , rn=''Res'' + convert(varchar(10),row_number() over (
              partition by id_number, bk_no 
              order by     res 
          ))
      from t
      ) as a
 pivot (max([Res]) for [rn] in (' + @cols + ') ) p';
 select @sql as CodeGenerated;
 exec sp_executesql @sql;

返回:

+-----------------------------------------------------------------+
|                          CodeGenerated                          |
+-----------------------------------------------------------------+
|      select id_number, bk_no, [Res1],[Res2]                     |
|       from  (                                                   |
|         select                                                  |
|             id_number                                           |
|           , bk_no                                               |
|           , Res                                                 |
|           , rn='Res' + convert(varchar(10),row_number() over ( |
|                   partition by id_number, bk_no                 |
|                   order by     res                              |
|               ))                                                |
|           from t                                                |
|           ) as a                                                |
|      pivot (max([Res]) for [rn] in ([Res1],[Res2]) ) p          |
+-----------------------------------------------------------------+
+-----------+-------+---------+---------+
| id_number | bk_no |  Res1   |  Res2   |
+-----------+-------+---------+---------+
| LUC00003  | BK001 | CLARETH | MARC    |
| LUC00009  | BK001 | CLARETH | MICHAEL |
+-----------+-------+---------+---------+