gpt4 book ai didi

sql - 如何设计从行创建动态列的查询

转载 作者:行者123 更新时间:2023-12-02 12:51:15 25 4
gpt4 key购买 nike

我有数据

表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 的最大列数,我想创建列名称,然后转换列中的行。这可以使用 sql 查询来完成吗?

最佳答案

我创建了一个名为“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 值的原因是每个 CASE 语句中都有 ELSE。如果您希望使用 NULL 值,只需根据需要删除 ELSE 0ELSE '' 即可。

我目前不知道是否可以使其通用,例如:处理未知数量的不同 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

根据您最喜欢的格式和方法,至少列出了您的选择。

关于sql - 如何设计从行创建动态列的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3720728/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com