以上是我想要使用的一组示例数据。我如何构建一个动态返回以下列和行的查询。
我需要查询来生成一个表,该表包含每个分组年份和每个M1,M2,M3 ...列的列:
Simulation,Year2000M1,Year2000M2,Year2000M3,Year2000M4,Year2000M5,Year2001M1...
1,1,2,3,4,5,6...
2,26,27,28,29,30,31...
3,51,52,53,54,55,56...
我真的不知道从哪里开始。我以前从未在行中生成过列。
答案 0 :(得分:1)
这是带有SQL Server的列动态版本(我不知道您使用的是哪个RDBMS)
DECLARE @Years NVARCHAR(4000)
SET @Years = ''
SELECT
@Years = COALESCE(CASE
WHEN @Years = '' THEN 'Year' + CAST(Year AS NVARCHAR) + COLUMN_NAME
ELSE @Years +', ' + 'Year' + CAST(Year AS NVARCHAR) + COLUMN_NAME END, '')
FROM
INFORMATION_SCHEMA.COLUMNS
CROSS JOIN (SELECT DISTINCT Year FROM Test) Years
WHERE
TABLE_NAME = 'Test' AND
COLUMN_NAME LIKE 'M%'
DECLARE @Columns NVARCHAR(4000)
SET @Columns = ''
SELECT
@Columns = COALESCE(CASE
WHEN @Columns = '' THEN COLUMN_NAME
ELSE @Columns +', ' + COLUMN_NAME END, '')
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'Test' AND
COLUMN_NAME LIKE 'M%'
DECLARE @Query NVARCHAR(MAX)
SET @Query = '
SELECT
*
FROM
(
SELECT
Simulation, (''Year'' + CAST(Year AS VARCHAR) + M) AS YearM, Value
FROM
(
SELECT
Simulation, Year, M, Value
FROM
(SELECT * FROM Test) p
UNPIVOT
(Value FOR M IN
(' + @Columns + ')
) AS unpvt) data
) Data1
PIVOT (
MAX(Value) FOR YearM IN (' + @Years + ')) AS result'
EXECUTE(@Query)
这里有一个演示版 http://sqlfiddle.com/#!6/e7c99/49
这是解决问题的另一种方法,但是使用静态列(没有UNPIVOT / PIVOT)。
SELECT
Simulation,
SUM(CASE WHEN Year = 2000 THEN M1 ELSE 0 END) Year2000M1,
SUM(CASE WHEN Year = 2000 THEN M2 ELSE 0 END) Year2000M2,
SUM(CASE WHEN Year = 2000 THEN M3 ELSE 0 END) Year2000M3,
SUM(CASE WHEN Year = 2000 THEN M4 ELSE 0 END) Year2000M4,
SUM(CASE WHEN Year = 2000 THEN M5 ELSE 0 END) Year2000M5,
SUM(CASE WHEN Year = 2001 THEN M1 ELSE 0 END) Year2001M1,
SUM(CASE WHEN Year = 2001 THEN M2 ELSE 0 END) Year2001M2,
SUM(CASE WHEN Year = 2001 THEN M3 ELSE 0 END) Year2001M3,
SUM(CASE WHEN Year = 2001 THEN M4 ELSE 0 END) Year2001M4,
SUM(CASE WHEN Year = 2001 THEN M5 ELSE 0 END) Year2001M5,
SUM(CASE WHEN Year = 2002 THEN M1 ELSE 0 END) Year2002M1,
SUM(CASE WHEN Year = 2002 THEN M2 ELSE 0 END) Year2002M2,
SUM(CASE WHEN Year = 2002 THEN M3 ELSE 0 END) Year2002M3,
SUM(CASE WHEN Year = 2002 THEN M4 ELSE 0 END) Year2002M4,
SUM(CASE WHEN Year = 2002 THEN M5 ELSE 0 END) Year2002M5,
SUM(CASE WHEN Year = 2003 THEN M1 ELSE 0 END) Year2003M1,
SUM(CASE WHEN Year = 2003 THEN M2 ELSE 0 END) Year2003M2,
SUM(CASE WHEN Year = 2003 THEN M3 ELSE 0 END) Year2003M3,
SUM(CASE WHEN Year = 2003 THEN M4 ELSE 0 END) Year2003M4,
SUM(CASE WHEN Year = 2003 THEN M5 ELSE 0 END) Year2003M5,
SUM(CASE WHEN Year = 2004 THEN M1 ELSE 0 END) Year2004M1,
SUM(CASE WHEN Year = 2004 THEN M2 ELSE 0 END) Year2004M2,
SUM(CASE WHEN Year = 2004 THEN M3 ELSE 0 END) Year2004M3,
SUM(CASE WHEN Year = 2004 THEN M4 ELSE 0 END) Year2004M4,
SUM(CASE WHEN Year = 2004 THEN M5 ELSE 0 END) Year2004M5
FROM
Test
GROUP BY
Simulation
这里有一个演示版 http://sqlfiddle.com/#!6/e7c99/18
这是解决问题的另一种方法,但是使用静态列(使用UNPIVOT / PIVOT)
SELECT
*
FROM
(
SELECT
Simulation, ('Year' + CAST(Year AS VARCHAR) + M) AS YearM, Value
FROM
(
SELECT
Simulation, Year, M, Value
FROM
(SELECT * FROM Test) p
UNPIVOT
(Value FOR M IN
(M1, M2, M3, M4, M5)
) AS unpvt) data
) Data1
PIVOT (
MAX(Value) FOR YearM IN (
Year2000M1,Year2000M2,Year2000M3,Year2000M4,Year2000M5,
Year2001M1,Year2001M2,Year2001M3,Year2001M4,Year2001M5,
Year2002M1,Year2002M2,Year2002M3,Year2002M4,Year2002M5,
Year2003M1,Year2003M2,Year2003M3,Year2003M4,Year2003M5,
Year2004M1,Year2004M2,Year2004M3,Year2004M4,Year2004M5)) AS result
这里有一个演示版 http://sqlfiddle.com/#!6/e7c99/17
希望这有帮助