我有以下数据集
Date Field1 Col1 Col2 Col3
2012/07/02 Customer1 CL DS RT
2012/07/03 Customer1 DS RT 700
2012/07/04 Customer1 DS RT 700
2012/07/02 Customer2 CL DS RT
2012/07/03 Customer2 DS RT 1500
2012/07/04 Customer2 DS RT 1500
2012/07/02 Customer3 CL DS RT
2012/07/03 Customer3 DS RT 6000
2012/07/04 Customer3 DS RT 6000
2012/07/02 Customer4 CL RC RT
2012/07/03 Customer4 RC RT 4900
2012/07/04 Customer4 RC RT 4900
我想输出如下:
Field1 2012/07/02 2012/07/03 2012/07/04
Col1 Customer1 CL DS DS
Col2 Customer1 DS RT RT
Col3 Customer1 RT 700 700
Col1 Customer2 CL DS DS
Col2 Customer2 DS RT RT
Col3 Customer2 RT 1500 1500
Col1 Customer3 CL DS DS
Col2 Customer3 DS RT RT
Col3 Customer3 RT 6000 6000
Col1 Customer4 CL RC RC
Col2 Customer4 RC RT RT
Col3 Customer4 RT 4900 4900
问题还在于我有一定数量的客户(Field1)&未定期的日期。
答案 0 :(得分:2)
您要做的事情被称为PIVOT
。有两种方法可以完成这些操作,可以使用静态数据透视表来硬编码所有要转换的值,也可以使用动态数据透视表来确定执行时的值。
静态版(见SQL Fiddle with Demo):
select *
from
(
select dt, field1, col, value
from yourTable
unpivot
(
value for col in (col1, col2, col3)
) u
)x1
pivot
(
min(value)
for dt in ([2012-07-02], [2012-07-03], [2012-07-04])
) p
Dynamic Pivot(参见SQL Fiddle with Demo):
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@colsPivot as NVARCHAR(MAX)
select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('yourTable') and
C.name like 'col%'
for xml path('')), 1, 1, '')
select @colsPivot = STUFF((SELECT distinct ', ' + QUOTENAME(convert(char(10), dt, 120))
from yourTable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query =
'SELECT col, field1, ' + +@colsPivot+ '
FROM
(
select dt, field1, col, value
from yourTable
unpivot
(
value for col in ('+ @colsUnpivot+')
) u
)x1
pivot
(
min(value)
for dt in ('+@colsPivot+')
) p '
exec(@query)
当您不知道需要转换为列的项目数时,动态数据透视表是一个很好的选择。两者都会产生相同的结果。
编辑#1,如果你想要特定顺序的日期列 - desc等,那么你将使用以下内容来获取日期(见SQL Fiddle with Demo):
select @colsPivot = STUFF((SELECT ', ' + QUOTENAME(convert(char(10), dt, 120))
from yourTable
group by dt
ORDER by dt desc
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
答案 1 :(得分:0)
如果没有聚合,您不需要这样做,但您确实需要使用动态SQL来执行此操作。搜索“SQL Dynamic Pivot”,你会发现很多关于它的帖子。 喜欢:SQL Server dynamic PIVOT query?
但更好的方法是在客户端执行此操作,因为SQL的客户更愿意知道提前生成了哪些列。
答案 2 :(得分:0)
您必须使用SQL Server Pivot query来解决问题。
您可以使用以下查询:
CREATE TABLE mytable(date DATE, Field1 NVARCHAR(50), col1 NVARCHAR(30), col2 NVARCHAR(30),col3 NVARCHAR(30))
INSERT INTO mytable(date,Field1,col1,col2,col3)
VALUES('2012/07/02','Customer1','CL','DS','RT')
...
SELECT Col, Field1, [2012/07/02],[2012/07/03],[2012/07/04]
FROM (SELECT Field1, 'Col1' AS Col, Date, Col1 AS ColVal
FROM MyTable
UNION ALL
SELECT Field1, 'Col2' , Date, Col2 AS ColVal
FROM MyTable
UNION ALL
SELECT Field1, 'Col3' , Date, Col3 AS Col
FROM MyTable
)AS P
PIVOT (MIN(Colval) FOR Date IN ([2012/07/02],[2012/07/03],[2012/07/04])) AS Pvt
ORDER BY Field1, Col