透视 SQL 语句

发布于 2024-08-18 08:26:38 字数 503 浏览 3 评论 0原文

我有一个像这样的表(当然还有更多的值,但你明白了):

ID      Name
---     ----
1       A
1       B
2       C
3       D
4       A
4       D
4       E
4       F
4       G
4       H

我想编写一个输出这个的查询,因为一个 ID 不能有超过 6 个名称。

ID      Name1        Name2       Name3     Name4     Name5    Name6
---    ------        ------     ------    ------    ------    -----
1        A             B
2        C
3        D
4        A             D           E         F         G        H

I have a table like this (of course there are many more values but you get the idea):

ID      Name
---     ----
1       A
1       B
2       C
3       D
4       A
4       D
4       E
4       F
4       G
4       H

I want to write a query that would output this, given that an ID cannot have more than 6 names.

ID      Name1        Name2       Name3     Name4     Name5    Name6
---    ------        ------     ------    ------    ------    -----
1        A             B
2        C
3        D
4        A             D           E         F         G        H

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风筝有风,海豚有海 2024-08-25 08:26:38

尝试:

WITH rows AS (
   SELECT t.id,
          t.name,
          ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY t.name) 'rank'
     FROM TABLE t)
  SELECT r.id,
         MAX(CASE WHEN r.rank = 1 THEN r.name ELSE NULL END) AS Name1,
         MAX(CASE WHEN r.rank = 2 THEN r.name ELSE NULL END) AS Name2,
         MAX(CASE WHEN r.rank = 3 THEN r.name ELSE NULL END) AS Name3,
         MAX(CASE WHEN r.rank = 4 THEN r.name ELSE NULL END) AS Name4,
         MAX(CASE WHEN r.rank = 5 THEN r.name ELSE NULL END) AS Name5,
         MAX(CASE WHEN r.rank = 6 THEN r.name ELSE NULL END) AS Name6,
    FROM rows r
GROUP BY r.id

非 CTE 等效项:

SELECT r.id,
       MAX(CASE WHEN r.rank = 1 THEN r.name ELSE NULL END) AS Name1,
       MAX(CASE WHEN r.rank = 2 THEN r.name ELSE NULL END) AS Name2,
       MAX(CASE WHEN r.rank = 3 THEN r.name ELSE NULL END) AS Name3,
       MAX(CASE WHEN r.rank = 4 THEN r.name ELSE NULL END) AS Name4,
       MAX(CASE WHEN r.rank = 5 THEN r.name ELSE NULL END) AS Name5,
       MAX(CASE WHEN r.rank = 6 THEN r.name ELSE NULL END) AS Name6,
  FROM (SELECT t.id,
               t.name,
               ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY t.name) 'rank'
          FROM TABLE t) r
GROUP BY r.id

参考:

Try:

WITH rows AS (
   SELECT t.id,
          t.name,
          ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY t.name) 'rank'
     FROM TABLE t)
  SELECT r.id,
         MAX(CASE WHEN r.rank = 1 THEN r.name ELSE NULL END) AS Name1,
         MAX(CASE WHEN r.rank = 2 THEN r.name ELSE NULL END) AS Name2,
         MAX(CASE WHEN r.rank = 3 THEN r.name ELSE NULL END) AS Name3,
         MAX(CASE WHEN r.rank = 4 THEN r.name ELSE NULL END) AS Name4,
         MAX(CASE WHEN r.rank = 5 THEN r.name ELSE NULL END) AS Name5,
         MAX(CASE WHEN r.rank = 6 THEN r.name ELSE NULL END) AS Name6,
    FROM rows r
GROUP BY r.id

Non CTE equivalent:

SELECT r.id,
       MAX(CASE WHEN r.rank = 1 THEN r.name ELSE NULL END) AS Name1,
       MAX(CASE WHEN r.rank = 2 THEN r.name ELSE NULL END) AS Name2,
       MAX(CASE WHEN r.rank = 3 THEN r.name ELSE NULL END) AS Name3,
       MAX(CASE WHEN r.rank = 4 THEN r.name ELSE NULL END) AS Name4,
       MAX(CASE WHEN r.rank = 5 THEN r.name ELSE NULL END) AS Name5,
       MAX(CASE WHEN r.rank = 6 THEN r.name ELSE NULL END) AS Name6,
  FROM (SELECT t.id,
               t.name,
               ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY t.name) 'rank'
          FROM TABLE t) r
GROUP BY r.id

Reference:

愿得七秒忆 2024-08-25 08:26:38

我创建了一个名为pivot_query 的存储过程,以使PIVOT 语句更加灵活。它的来源是此处。还有一个如何使用它的示例

借用下面 OMG Ponies 的一段代码,并稍微更改一下查询,
那么对pivot_query的调用将如下所示:

declare @mySQL varchar(MAX)

set @mySQL = '
SELECT
   t.id,
   t.name,
   ''Name'' + cast(ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY t.name) as varchar(2)) rank
FROM
   TestData t'

exec pivot_query @mySQL, 'Id', 'rank', 'max(Name)'

现在的结果如下所示:

Id         Name1 Name2 Name3 Name4 Name5 Name6 
---------- ----- ----- ----- ----- ----- ----- 
1          A     B     NULL  NULL  NULL  NULL  
2          C     NULL  NULL  NULL  NULL  NULL  
3          D     NULL  NULL  NULL  NULL  NULL  
4          A     D     E     F     G     H     

但不完全确定您要显示的内容。 :-)

虽然这本质上不会将输出限制为 6 个名称列,但它会继续上升,除非您添加一个 where 子句来专门排除 6 以上的排名。

I created a stored procedure named pivot_query to make the PIVOT statement a little more flexible. The source for it is here. There is also an example of how to use it.

Borrowing a piece of code from OMG Ponies below, and changing the query a bit,
then the call to pivot_query would look like this:

declare @mySQL varchar(MAX)

set @mySQL = '
SELECT
   t.id,
   t.name,
   ''Name'' + cast(ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY t.name) as varchar(2)) rank
FROM
   TestData t'

exec pivot_query @mySQL, 'Id', 'rank', 'max(Name)'

and the results now look like this:

Id         Name1 Name2 Name3 Name4 Name5 Name6 
---------- ----- ----- ----- ----- ----- ----- 
1          A     B     NULL  NULL  NULL  NULL  
2          C     NULL  NULL  NULL  NULL  NULL  
3          D     NULL  NULL  NULL  NULL  NULL  
4          A     D     E     F     G     H     

Not exactly sure what you're trying to show, though. :-)

This will not intrinsically limit the output to the 6 name columns though, it will keep going up unless you add a where clause to specifically exclude ranks above 6.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文