【问题标题】:Getting the top 6 items in a column to pivot to a row in SQL获取列中的前 6 个项目以在 SQL 中旋转到一行
【发布时间】:2013-04-08 19:46:39
【问题描述】:

我无法在 SQL 中获取要旋转的列。我想将前 6 个结果从一列转换为一行。我正在旋转的列一开始可能有少于或多于 6 个结果,但我想忽略前 6 名之外的任何内容。

我的 Table1 如下所示:

ID | GroupID | CodeNum
----------------------
1  | 1       | 111
2  | 1       | 222
3  | 1       | 333
4  | 1       | 444
5  | 1       | 555
6  | 1       | 666
7  | 1       | 777
8  | 2       | 111
9  | 2       | 888
10 | 3       | 999

我希望我的输出看起来像这样:

GroupID | Code1 | Code2 | Code3 | Code4 | Code5 | Code6
-------------------------------------------------------
1       | 111   | 222   | 333   | 444   | 555   | 666
2       | 111   | 888   |       |       |       |
3       | 999   |       |       |       |       |

我试过这段代码:

SELECT  GroupID
        , [Code1] = CASE WHEN rn = 1 THEN CodeNum END
        , [Code2] = CASE WHEN rn = 2 THEN CodeNum END
        , [Code3] = CASE WHEN rn = 3 THEN CodeNum END
        , [Code4] = CASE WHEN rn = 4 THEN CodeNum END
        , [Code5] = CASE WHEN rn = 5 THEN CodeNum END
        , [Code6] = CASE WHEN rn = 6 THEN CodeNum END
FROM    (
            SELECT  TOP 6 GroupID
                    , rn = ROW_NUMBER() OVER (ORDER BY ID)
                    , CodeNum
            FROM    Table1      
        ) q
GROUP BY
        GroupID

但我收到一条错误消息,上面写着Column 'q.rn' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

当 CodeNum 每个 GroupID 可能有 1 到 12 个值时,有没有办法做到这一点?

【问题讨论】:

    标签: sql-server tsql pivot


    【解决方案1】:

    由于您使用的是GROUP BY,因此您需要按SELECT 中的所有项目分组或使用聚合函数。

    您将需要使用以下内容来获取结果,然后将行 pivot 到列中:

    SELECT  GroupID
            , [Code1] = max(CASE WHEN rn = 1 THEN CodeNum END)
            , [Code2] = max(CASE WHEN rn = 2 THEN CodeNum END)
            , [Code3] = max(CASE WHEN rn = 3 THEN CodeNum END)
            , [Code4] = max(CASE WHEN rn = 4 THEN CodeNum END)
            , [Code5] = max(CASE WHEN rn = 5 THEN CodeNum END)
            , [Code6] = max(CASE WHEN rn = 6 THEN CodeNum END)
    FROM    
    (
      SELECT  GroupID
       , rn = ROW_NUMBER() OVER (PARTITION BY GroupID ORDER BY ID)
       , CodeNum
      FROM    Table1      
    ) q
    GROUP BY GroupID
    

    SQL Fiddle with Demo

    您会注意到我删除了TOP 6 并添加了partition by GroupId。如果您使用TOP,那么您将只返回第一个 ID 的值。分区将返回每个 ID 的行,但外部选择仅返回前 6 行。

    这给出了结果:

    | GROUPID | CODE1 |  CODE2 |  CODE3 |  CODE4 |  CODE5 |  CODE6 |
    ----------------------------------------------------------------
    |       1 |   111 |    222 |    333 |    444 |    555 |    666 |
    |       2 |   111 |    888 | (null) | (null) | (null) | (null) |
    |       3 |   999 | (null) | (null) | (null) | (null) | (null) |
    

    注意,根据您的 SQL Server 版本,这也可以使用 PIVOT 函数编写:

    select GroupID,
      [1] as Code1, 
      [2] as Code2, 
      [3] as Code3, 
      [4] as Code4, 
      [5] as Code5, 
      [6] as Code6
    from
    (
      SELECT  GroupID
       , rn = ROW_NUMBER() OVER (PARTITION BY GroupID ORDER BY ID)
       , CodeNum
      FROM Table1    
    ) d
    pivot
    (
      max(codenum)
      for rn in ([1], [2], [3], [4], [5], [6])
    ) piv;
    

    SQL Fiddle with Demo

    【讨论】:

      猜你喜欢
      • 2013-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-15
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多