我有数据
表1
ID Name
-----------
1 n1
2 n2
3 n4
表2
FID YearS Val
----------------------
1 2008 Up
1 2009 Down
1 2010 Up
2 2000 Up
2 2001 Down
2 2002 Up
2 2003 Up
3 2009 Down
3 2010 Up
我想以下列格式返回数据:
ID Yr1 Val1 Yr2 Val2 Yr3 Val3 Yr4 Val4
--------------------------------------------------------
1 2008 Up 2009 Down 2010 Up NULL Null
2 2000 Up 2001 Down 2002 Up 2003 Up
3 2009 Down 2010 Up NULL NULL NULL Null
基于ID的最大列数i我想创建列名,然后转换列中的行。这可以使用SQL查询吗?
答案 0 :(得分:5)
我创建了一个名为“Table2”的表,其中包含您在表2标题下显示的数据。
这是我在SQL Server 2008中使用的SQL。
WITH RankedValues AS
(
SELECT
FID AS ID,
YearS,
ROW_NUMBER() OVER(PARTITION BY FID ORDER BY YearS) AS YearSRank,
Val
FROM
Table2
)
SELECT
ID,
MAX((CASE WHEN YearSRank = 1 THEN YearS ELSE 0 END)) AS Yr1,
MAX((CASE WHEN YearSRank = 1 THEN Val ELSE '' END)) AS Val1,
MAX((CASE WHEN YearSRank = 2 THEN YearS ELSE 0 END)) AS Yr2,
MAX((CASE WHEN YearSRank = 2 THEN Val ELSE '' END)) AS Val2,
MAX((CASE WHEN YearSRank = 3 THEN YearS ELSE 0 END)) AS Yr3,
MAX((CASE WHEN YearSRank = 3 THEN Val ELSE '' END)) AS Val3,
MAX((CASE WHEN YearSRank = 4 THEN YearS ELSE 0 END)) AS Yr4,
MAX((CASE WHEN YearSRank = 4 THEN Val ELSE '' END)) AS Val4
FROM
RankedValues
GROUP BY
ID
以上SQL将导致:
ID Yr1 Val1 Yr2 Val2 Yr3 Val3 Yr4 Val4
---------------------------------------------------------------------
1 2008 Up 2009 Down 2010 Up 0
2 2000 Up 2001 Down 2002 Up 2003 Up
3 2009 Down 2010 Up 0 0
您没有看到NULL
值的原因是每个ELSE
语句中的CASE
。
如果您想要NULL
个值,只需根据需要删除ELSE 0
和ELSE ''
。
我目前还不知道是否有可能使这种通用,例如:处理未知数量的不同FID,因为这也意味着通常生成列名(Yr1,al1,Yr2等)
你可以通过动态SQL实现这一点,但由于我不是动态SQL的忠实粉丝,我会尝试另外一种处理它的方法。
- 编辑(为完整性添加了透视方法) -
我查看了Joe Stefanelli发布的链接,并根据您的要求添加了以下SQL。虽然我不喜欢动态SQL的想法,但我无法在这个特定的实例中找到任何其他方法。
DECLARE @query VARCHAR(4000)
DECLARE @years VARCHAR(2000)
SELECT @years = STUFF((
SELECT DISTINCT
'],[' + ltrim(str(YearS))
FROM Table2
ORDER BY '],[' + ltrim(str(YearS))
FOR XML PATH('')), 1, 2, '') + ']'
SET @query =
'SELECT * FROM
(
SELECT FID AS ID,YearS,Val
FROM Table2
) AS t
PIVOT (MAX(Val) FOR YearS IN (' + @years + ')) AS pvt'
EXECUTE (@query)
这将导致以下结果:
ID 2000 2001 2002 2003 2008 2009 2010
---------------------------------------------------------
1 NULL NULL NULL NULL Up Down Up
2 Up Down Up Up NULL NULL NULL
3 NULL NULL NULL NULL NULL Down Up
根据您最喜欢的格式和方法,至少您可以选择自己的选项。
答案 1 :(得分:3)
答案 2 :(得分:1)
此查询应该有帮助
;WITH cte AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY FID ORDER BY FID, YearS) AS NUMBER
FROM Table2
)
SELECT t.ID, MAX(CASE WHEN cte.number = 1 THEN cte.YearS END) as yr1, MAX(CASE WHEN cte.number = 1 THEN cte.Val END) as val1,
MAX(CASE WHEN cte.number = 2 THEN cte.YearS END) as yr2, MAX(CASE WHEN cte.number = 2 THEN cte.Val END) as val2,
MAX(CASE WHEN cte.number = 3 THEN cte.YearS END) as yr3, MAX(CASE WHEN cte.number = 3 THEN cte.Val END) as val3,
MAX(CASE WHEN cte.number = 4 THEN cte.YearS END) as yr4, MAX(CASE WHEN cte.number = 4 THEN cte.Val END) as val4
FROM Table1 T
JOIN cte ON t.ID = cte.FID
GROUP BY t.ID