如何将行转换为列?

时间:2015-10-07 07:48:08

标签: sql sql-server

我有一个这样的表,此表中的所有用户只有两个功能

+-------+---------+-----------+----------+
| User  | Feature | StartDate | EndDate  |
+-------+---------+-----------+----------+
| Peter |   F1    | 2015/1/1  | 2015/2/1 |
| Peter |   F2    | 2015/3/1  | 2015/4/1 |
| John  |   F1    | 2015/5/1  | 2015/6/1 |
| John  |   F2    | 2015/7/1  | 2015/8/1 |
+-------+---------+-----------+----------+

我想转型为

+-------+--------------+------------+--------------+------------+
| User  | F1_StartDate | F1_EndDate | F2_StartDate | F2_EndDate |
+-------+--------------+------------+--------------+------------+
| Peter |   2015/1/1   |  2015/2/1  |   2015/3/1   |  2015/4/1  |
| John  |   2015/5/1   |  2015/6/1  |   2015/7/1   |  2015/8/1  |
+-------+--------------+------------+--------------+------------+

4 个答案:

答案 0 :(得分:1)

如果您正在使用SQL Server 2005或任何机会,PIVOT正是您所寻找的。

答案 1 :(得分:0)

执行此类操作的最佳方法是使用简单的group by语句。这应该适用于所有主要的ODBMS:

select user,
       max(case when feature='F1' then StartDate else null end) F1_StartDate,
       max(case when feature='F1' then EndDate else null end) F1_EndDate,
       max(case when feature='F2' then StartDate else null end) F2_StartDate,
       max(case when feature='F2' then EndDate else null end) F2_EndDate
    from table 
    group by user

注意:正如评论中所提到的,这通常是不好的做法,因为根据您的需要,它可能会使数据难以使用。但是,如果您的数值很少,数量有限,则有时会有意义。

答案 2 :(得分:0)

像这样使用UNPIVOT & PIVOT

测试数据:

DECLARE @t table
  (User1 varchar(20),Feature char(2),StartDate date,EndDate date)
INSERT @t values
('Pete','F1','2015/1/1 ','2015/2/1'),
('Pete','F2','2015/3/1 ','2015/4/1'),
('John','F1','2015/5/1 ','2015/6/1'),
('John','F2','2015/7/1 ','2015/8/1')

查询:

;WITH CTE AS
(
  SELECT User1, date1, Feature + '_' +  Seq cat
  FROM @t as p  
  UNPIVOT      
  (date1 FOR Seq IN           
  ([StartDate], [EndDate]) ) AS unpvt  
)
SELECT * FROM CTE
PIVOT
(MIN(date1)
FOR cat
IN ([F1_StartDate],[F1_EndDate],[F2_StartDate],[F2_EndDate])
) as p

结果:

User1  F1_StartDate  F1_EndDate  F2_StartDate  F2_EndDate
John   2015-05-01    2015-06-01  2015-07-01    2015-08-01
Pete   2015-01-01    2015-02-01  2015-03-01    2015-04-01

答案 3 :(得分:0)

对于CTE

,这是一个黑客攻击
;WITH CTE AS (
SELECT [User], [Feature] + '_StartDate' AS [Type], StartDate AS [Date]
FROM Table1
UNION ALL
SELECT [User], [Feature] + '_EndDate' AS [Type], EndDate AS [Date]
FROM Table1)
SELECT * FROM CTE
PIVOT(MAX([Date]) FOR [Type] IN ([F1_StartDate],[F2_StartDate], [F1_EndDate], [F2_EndDate])) PIV