当尝试获取最后 5 个值作为列时,T-SQL 将行转换为列?

发布于 2024-12-09 06:22:14 字数 2015 浏览 6 评论 0原文

我正在使用 MS SQL Server 2005。

我认为 PIVOT 可以在这里帮助我,但我不明白。一定是我想多了。 输入

create table #myrows (id char(1), seq_i int, val char(10))

insert into #myrows values('A',1, 'A1') 
insert into #myrows values('A',2, 'A2') 
insert into #myrows values('A',3, 'A3') 
insert into #myrows values('A',4, 'A4') 
insert into #myrows values('A',5, 'A5') 
insert into #myrows values('A',6, 'A6') 
insert into #myrows values('A',7, 'A7') 
insert into #myrows values('A',8, 'A8') 
insert into #myrows values('A',9, 'A9') 
insert into #myrows values('A',10, 'A10') 

insert into #myrows values('B',1, 'B1') 
insert into #myrows values('B',2, 'B2') 
insert into #myrows values('B',3, 'B3') 
insert into #myrows values('B',4, 'B4') 
insert into #myrows values('B',5, 'B5') 
insert into #myrows values('B',6, 'B6') 

insert into #myrows values('C',1, 'C1') 
insert into #myrows values('C',2, 'C2') 
insert into #myrows values('C',3, 'C3') 

这是当我传递 id 时我可以使用 T-SQL 完成的 。但我似乎可以创建一个简单的 sql 视图,不需要我向它发送 id。下面是 T-SQL,它为我提供了一个 id 所需的输出:

DECLARE @max_hierarchy int
DECLARE @code CHAR(1)

select @code = 'C'

SELECT  @max_hierarchy = max(seq_i)
FROM #myrows
WHERE id=@code

SELECT top 1
(SELECT val from #myrows WHERE id=@code AND seq_i = @max_hierarchy) AS 'Level1',
(SELECT val from #myrows WHERE id=@code AND seq_i = @max_hierarchy-1) AS 'Level2',
(SELECT val from #myrows WHERE id=@code AND seq_i = @max_hierarchy-2) AS 'Level3',
(SELECT val from #myrows WHERE id=@code AND seq_i = @max_hierarchy-3) AS 'Level4',
(SELECT val from #myrows WHERE id=@code AND seq_i = @max_hierarchy-4) AS 'Level5'
from #myrows
WHERE id=@code

理想情况下,这将是我正在寻找的 SQL 输出:

Code Level1      Level2      Level3      Level4      Level5
---- ----------- ----------- ----------- ----------- -----------
A    A10         A9          A8          A7          A6
B    B6          B5          B4          B3          B2
C    C3          C2          C1          NULL        NULL   

I am using MS SQL Server 2005.

I think PIVOT could help me here, but I can't figure it out. I must be over thinking.
Here is the input

create table #myrows (id char(1), seq_i int, val char(10))

insert into #myrows values('A',1, 'A1') 
insert into #myrows values('A',2, 'A2') 
insert into #myrows values('A',3, 'A3') 
insert into #myrows values('A',4, 'A4') 
insert into #myrows values('A',5, 'A5') 
insert into #myrows values('A',6, 'A6') 
insert into #myrows values('A',7, 'A7') 
insert into #myrows values('A',8, 'A8') 
insert into #myrows values('A',9, 'A9') 
insert into #myrows values('A',10, 'A10') 

insert into #myrows values('B',1, 'B1') 
insert into #myrows values('B',2, 'B2') 
insert into #myrows values('B',3, 'B3') 
insert into #myrows values('B',4, 'B4') 
insert into #myrows values('B',5, 'B5') 
insert into #myrows values('B',6, 'B6') 

insert into #myrows values('C',1, 'C1') 
insert into #myrows values('C',2, 'C2') 
insert into #myrows values('C',3, 'C3') 

I can do it with T-SQL when I passing the id. But I seems like there is an easy sql view that I could create that doesn't require me to send it the id. Here is the T-SQL that gets me the output I want for one id:

DECLARE @max_hierarchy int
DECLARE @code CHAR(1)

select @code = 'C'

SELECT  @max_hierarchy = max(seq_i)
FROM #myrows
WHERE id=@code

SELECT top 1
(SELECT val from #myrows WHERE id=@code AND seq_i = @max_hierarchy) AS 'Level1',
(SELECT val from #myrows WHERE id=@code AND seq_i = @max_hierarchy-1) AS 'Level2',
(SELECT val from #myrows WHERE id=@code AND seq_i = @max_hierarchy-2) AS 'Level3',
(SELECT val from #myrows WHERE id=@code AND seq_i = @max_hierarchy-3) AS 'Level4',
(SELECT val from #myrows WHERE id=@code AND seq_i = @max_hierarchy-4) AS 'Level5'
from #myrows
WHERE id=@code

Ideally this would be be my output of SQL I am looking for:

Code Level1      Level2      Level3      Level4      Level5
---- ----------- ----------- ----------- ----------- -----------
A    A10         A9          A8          A7          A6
B    B6          B5          B4          B3          B2
C    C3          C2          C1          NULL        NULL   

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

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

发布评论

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

评论(1

巷雨优美回忆 2024-12-16 06:22:14

由于您只需要前 5 个级别,因此不需要任何动态旋转,这应该可行:

with cte as (
select id, seq_i, val, ROW_NUMBER() over (partition by id order by seq_i desc) rn
from #myrows
)
select 
  id,
  max(case rn when 1 then val else null end) Level1,
  max(case rn when 2 then val else null end) Level2,
  max(case rn when 3 then val else null end) Level3,
  max(case rn when 4 then val else null end) Level4,
  max(case rn when 5 then val else null end) Level5
from cte
group by id

更新

现在,如果您想让事情变得更有趣并让您的动态级别,这是一个不那么简单但又很有趣的编码解决方案:

create table #cte (id char(1), seq_i int, val char(10), level varchar(10))

;with cte as (
select id, seq_i, val, ROW_NUMBER() over (partition by id order by seq_i desc) rn
from #myrows
)
insert into #cte (id, seq_i, val, level)
select id, seq_i, val, 
       'Level' + right('000' + cast(rn as varchar), 4) from cte 

DECLARE @cols VARCHAR(1000)
DECLARE @sqlquery VARCHAR(2000)

SELECT  @cols = STUFF(( SELECT distinct  ',' + QuoteName(level)
                        FROM #cte FOR XML PATH('')  ), 1, 1, '') 

select @cols 

SET @sqlquery = 'SELECT * FROM
      (SELECT id, level, val
       FROM #cte ) base
       PIVOT (max(val) FOR [level]
       IN (' + @cols + ')) AS finalpivot'

EXECUTE ( @sqlquery )

Since you want only the top 5 levels, you don't need any dynamic pivoting and this should work:

with cte as (
select id, seq_i, val, ROW_NUMBER() over (partition by id order by seq_i desc) rn
from #myrows
)
select 
  id,
  max(case rn when 1 then val else null end) Level1,
  max(case rn when 2 then val else null end) Level2,
  max(case rn when 3 then val else null end) Level3,
  max(case rn when 4 then val else null end) Level4,
  max(case rn when 5 then val else null end) Level5
from cte
group by id

Update

Now, if you want to make things more interesting and have your levels dynamically, here's the not-so-trivial-yet-lot-of-fun-on-coding solution:

create table #cte (id char(1), seq_i int, val char(10), level varchar(10))

;with cte as (
select id, seq_i, val, ROW_NUMBER() over (partition by id order by seq_i desc) rn
from #myrows
)
insert into #cte (id, seq_i, val, level)
select id, seq_i, val, 
       'Level' + right('000' + cast(rn as varchar), 4) from cte 

DECLARE @cols VARCHAR(1000)
DECLARE @sqlquery VARCHAR(2000)

SELECT  @cols = STUFF(( SELECT distinct  ',' + QuoteName(level)
                        FROM #cte FOR XML PATH('')  ), 1, 1, '') 

select @cols 

SET @sqlquery = 'SELECT * FROM
      (SELECT id, level, val
       FROM #cte ) base
       PIVOT (max(val) FOR [level]
       IN (' + @cols + ')) AS finalpivot'

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