0

我无法让列在 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 个值时,有没有办法做到这一点?

4

1 回答 1

4

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

您将需要使用以下内容来获取结果,然后行转换为列:

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

您会注意到我删除了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

于 2013-04-08T19:59:23.903 回答