我有一个数据表,如下所示
User Year Points Value
A 1997 1 10
A 1997 2 30
A 1997 3 40
A 1999 1 70
B 1993 1 7
B 1993 3 4
C 2001 1 10
.....
我希望将表格转换为:
User Year Points1 Points2 Points3 ....
A 1997 10 30 40
A 1999 70 null null
B 1993 7 null 4
C 2001 10 null null
......
点的范围在编译时是未知的,因此它不仅仅是从1到3。 它几乎就像将Points作为新表中的列标题。我认为SQL PIVOT是一个不错的选择,但我没有运气好玩。我正在使用SQL 2008。
答案 0 :(得分:2)
由于您提到SQL PIVOT
我猜您正在使用SQL Server 2005或更高版本或Oracle 11g
SQL 2005
SELECT [user], year, [1] as Point1, [2] as Point2, [3] as Point3
FROM
(
SELECT [user], year , points, Value
FROM table ) AS SourceTable
PIVOT
(
SUM(Value)
FOR Points IN ([1], [2], [3])
) AS PivotTable
ORDER BY [user]
请参阅此data.se query
的工作示例Oracle 11g
如果您使用的是Oracle 11g,那将是类似的事情(不确定字段别名)
SELECT *
FROM (
SELECT user, year , points, Value
FROM table )
PIVOT (SUM(Value) AS sum_value FOR (Points ) IN ('1' as Point1 ,
'2' as Point2,
'3' as Point3))
Order by User;
答案 1 :(得分:0)
也许这会有所帮助:
首先创建一些测试数据:
CREATE TABLE tblPoints ([User] VARCHAR(100), [Year] INT,Points INT,Value INT)
INSERT INTO tblPoints
SELECT 'A',1997,1,10 UNION ALL
SELECT 'A',1997,2,30 UNION ALL
SELECT 'A',1997,3,40 UNION ALL
SELECT 'A',1999,1,70 UNION ALL
SELECT 'B',1993,1,7 UNION ALL
SELECT 'B',1993,3,4 UNION ALL
SELECT 'C',2001,1,10
汇总列:
DECLARE @cols VARCHAR(MAX)
SELECT @cols = COALESCE(@cols + ','+QUOTENAME('Points'+Points),
QUOTENAME('Points'+Points))
FROM
(
SELECT
ROW_NUMBER() OVER(PARTITION BY tblPoints.Points ORDER BY tblPoints.Points) AS RowNbr,
CAST(tblPoints.Points AS VARCHAR(5)) AS Points
FROM
tblPoints
) AS tbl
WHERE
tbl.RowNbr=1
然后创建动态sql并执行它:
DECLARE @query NVARCHAR(4000)=
N'SELECT
*
FROM
(
SELECT
tblPoints.[User],
tblPoints.[Year],
''Points''+CAST(tblPoints.Points AS VARCHAR(5)) AS Points,
tblPoints.Value
FROM
tblPoints
) AS p
PIVOT
(
SUM(Value) FOR Points IN('+@cols+')
) AS pvt
ORDER BY [User]'
EXECUTE(@query)
因为我不想要点表:
DROP TABLE tblPoints