SQL pivot将行展平为列

时间:2017-03-07 14:24:54

标签: sql-server tsql

我有一个如下所示的源表:

+--------------+----------+------+------------+-----------+
| vehicleindex | parentid | year |    make    |   model   |
+--------------+----------+------+------------+-----------+
|            1 |        1 | 2007 | TOYOTA     | SIENNA LE |
|            2 |        1 | 2005 | VOLKSWAGEN | JETTA GLS |
+--------------+----------+------+------------+-----------+

我想从这个表中选择输出如下:

+-------+--------+-----------+-------+------------+-----------+
| year1 | make1  |  model1   | year2 |   make2    |  model2   |
+-------+--------+-----------+-------+------------+-----------+
|  2007 | TOYOTA | SIELLA LE |  2005 | VOLKSWAGEN | JETTA GLS |
+-------+--------+-----------+-------+------------+-----------+

如何在带有数据透视表的SQL Server数据库上完成此操作?源表中总是有1或2辆车。在有1辆车的情况下,我希望Year2Make2Model2NULL

3 个答案:

答案 0 :(得分:4)

与SQLZim的答案类似。唯一不同的是,只要vehicleindex不是一致的1和2,就使用Window函数Row_Number()。

Select year1  = max(case when RN=1 then [year] end)
      ,make1  = max(case when RN=1 then make end)
      ,model1 = max(case when RN=1 then model end)
      ,year2  = max(case when RN=2 then [year] end)
      ,make2  = max(case when RN=2 then make end)
      ,model2 = max(case when RN=2 then model end)
 From (
        Select *
              ,RN = Row_Number() over (Partition By parentid Order By vehicleindex)
         From  YourTable
      ) A
 Group By parentid 
  

编辑:选项2 - 使用PIVOT

Select *
From (
        Select parentid
              ,item     = concat(B.item,Dense_Rank() over (Partition By parentid Order By vehicleindex))
              ,value
         From  YourTable
         Cross Apply ( values ('year' ,cast(Year as varchar(100)))
                             ,('make' ,make)
                             ,('model',model)
                      ) B (item,value)
     ) A
 Pivot (max(value) For [item] in ([year1],[make1],[model1],[year2],[make2],[model2]) ) p

答案 1 :(得分:1)

使用条件聚合:

select 
    parentid
  , year1  = max(case when vehicleindex=1 then [year] end)
  , make1  = max(case when vehicleindex=1 then make end)
  , model1 = max(case when vehicleindex=1 then model end)
  , year2  = max(case when vehicleindex=2 then [year] end)
  , make2  = max(case when vehicleindex=2 then make end)
  , model2 = max(case when vehicleindex=2 then model end)
from t
group by parentid

返回:

+----------+-------+------------+-----------+-------+------------+-----------+
| parentid | year1 |   make1    |  model1   | year2 |   make2    |  model2   |
+----------+-------+------------+-----------+-------+------------+-----------+
|        1 |  2007 | TOYOTA     | SIENNA LE | 2005  | VOLKSWAGEN | JETTA GLS |
|        2 |  2018 | TESLA      | MODEL 3   | NULL  | NULL       | NULL      |
+----------+-------+------------+-----------+-------+------------+-----------+

rextestder演示:http://rextester.com/ZTGXU25389

使用此测试数据:

create table t (
    vehicleindex int
  , parentid int
  , [year] int
  , make varchar(32)
  , model  varchar(32)
);
insert into t values 
  (1,1,2007,'TOYOTA    ','SIENNA LE')
, (2,1,2005,'VOLKSWAGEN','JETTA GLS')
, (1,2,2018,'TESLA','MODEL 3')

答案 2 :(得分:1)

不幸的是,如果您需要旋转3列,则需要创建3个独立的枢轴,然后将它们合并到最后:

textContent