如何设计用于从行创建动态列的查询 [英] How to design Query for creating dynamic columns from rows

查看:22
本文介绍了如何设计用于从行创建动态列的查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有数据

表 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

我想以下列格式返回数据:

I want to return data in following format:

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 查询吗?

Based on maximum no of columns for ID i want to create column names and then convert rows in columns. Is this possible to do using a sql query?

推荐答案

我创建了一个名为Table2"的表格,其中包含您在上面表格 2 标题下显示的数据.

I have created a table called "Table2", containing the data you have shown above under your Table 2 heading.

这是我在 SQL Server 2008 中使用的 SQL.

Here is the SQL I used in SQL Server 2008.

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 将导致:

The above SQL will result in this:

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 ''.

The reason you do not see NULL values is because of the ELSE in each CASE statement. If you rather have NULL values, simply remove the ELSE 0 and ELSE '' as required.

我目前不知道是否可以使这个通用,例如:处理未知数量的不同 FID,因为这也意味着生成列名(Yr1、al1、Yr2 等)一般.

I do not know at this time if it is possible to make this generic, e.g.: process an unknown amount of distinct FIDs, as this would also mean generating the column names (Yr1, al1, Yr2,etc..) generically.

您可以使用动态 SQL 实现这一点,但由于我不是动态 SQL 的忠实粉丝,因此我会尝试寻找另一种处理方法.

You could propably achieve this with dynamic SQL but as I'm not a big fan of dynamic SQL I would try and look into another way of dealing with that.

-- 编辑(为完整性添加了枢轴方法)--

-- Edit (Added pivot approach for completness)--

我查看了 Joe Stefanelli 发布的链接,并根据您的要求添加了以下 SQL.虽然我不喜欢动态 SQL 的想法,但在这个特定实例中我找不到任何其他方法.

I looked at the link Joe Stefanelli posted and I added the SQL below for your requirement. Though I do not like the idea of dynamic SQL I was unable to find any other way in this specific instance.

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

根据你最喜欢的格式和方法,至少你有你的选择.

Depending which format and approach you like best, at least you have your options lined out.

这篇关于如何设计用于从行创建动态列的查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆