[英]Conditional Unpivot SQL table
I have a table which looks like this <SubCodeReport3>
which has a column called Rank
. 我有一个看起来像这样的表
<SubCodeReport3>
,其中有一个名为Rank
的列。 For each row I need to the what is the Rank and based on that value I need to unpivot SubCode columns (SubCode1,SubCode2 & Subcode3 etc) and convert them into rows. 对于每一行,我需要什么是排名,并基于该值,我需要取消透视SubCode列(SubCode1,SubCode2和Subcode3等)并将其转换为行。
As seen above for a Rank 2 Subcode1 & SubCode2 have been unpivoted Rank 1 SubCode1 has been unpivoted Rank 3 Subcode1, Subcode2 & SubCode3 have been unpivoted. 如上所示,等级2的子代码1和子代码2已取消枢纽。等级1的子代码1已被取消枢纽。等级3子代码1,子代码2和SubCode3已取消枢纽。
there will not be case where the Rank is higher than the no. 排名不会高于排名。 of available SubCode columns.
可用的SubCode列。 Any Ideas?
有任何想法吗?
Cursor though rows ? 游标虽然行?
Here is some SQL to create this sample table 这是一些创建此示例表的SQL
USE TESTDB
GO
/****** Object: Table [dbo].[SubCodeReport3] Script Date: 10/6/2015 2:27:49 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[SubCodeReport3](
[ S-ID] [varchar](50) NULL,
[Rank] [smallint] NULL,
[AGE] [varchar](50) NULL,
[SchoolCode] [varchar](50) NULL,
[SubCode1] [varchar](50) NULL,
[SubCode2] [varchar](50) NULL,
[SubCode3] [varchar](50) NULL,
[SubCode4] [varchar](50) NULL,
[SubCode5] [varchar](50) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[SubCodeReport3] ([ S-ID], [Rank], [AGE], [SchoolCode], [SubCode1], [SubCode2], [SubCode3], [SubCode4], [SubCode5]) VALUES (N'25', 1, N'23', N'KEN-009', N'ENG', N'MAT', N'ZOO', N'', N'')
INSERT [dbo].[SubCodeReport3] ([ S-ID], [Rank], [AGE], [SchoolCode], [SubCode1], [SubCode2], [SubCode3], [SubCode4], [SubCode5]) VALUES (N'26', 1, N'21', N'DLK-009', N'ENG', N'', N'', N'', N'')
INSERT [dbo].[SubCodeReport3] ([ S-ID], [Rank], [AGE], [SchoolCode], [SubCode1], [SubCode2], [SubCode3], [SubCode4], [SubCode5]) VALUES (N'27', 2, N'25', N'DLK-006', N'MAT', N'ENG', N'STAT', N'', N'')
INSERT [dbo].[SubCodeReport3] ([ S-ID], [Rank], [AGE], [SchoolCode], [SubCode1], [SubCode2], [SubCode3], [SubCode4], [SubCode5]) VALUES (N'28', 1, N'21', N'HLI-005', N'ENG', N'', N'', N'', N'')
INSERT [dbo].[SubCodeReport3] ([ S-ID], [Rank], [AGE], [SchoolCode], [SubCode1], [SubCode2], [SubCode3], [SubCode4], [SubCode5]) VALUES (N'30', 3, N'22', N'INN-009', N'ENG', N'MAT', N'ZOO', N'GEO', N'')
Start with a CTE or derived table that does a full unpivot of the table, and adds a partitioned row_number so that for each row in the original table, SubCode1 will be on row_number 1, SubCode2 on row_number 2, etc. 从CTE或派生表开始,该表执行该表的完全取消操作,并添加一个分区的row_number,以便对于原始表中的每一行,SubCode1将位于row_number 1上,SubCode2将位于row_number 2上,等等。
Then select from that CTE where row_number is less than or equal to [Rank]. 然后从row_number小于或等于[Rank]的CTE中选择。
You need to CROSS JOIN to a table with sequential numbers: 您需要交叉联接到具有序号的表:
with cte as
(
select 1 as n
union all select 2
union all select 3
union all select 4
union all select 5
)
select Rank, Age, SchoolCode,
case n
when 1 then SubCode1
when 2 then SubCode2
when 3 then SubCode3
when 4 then SubCode4
when 5 then SubCode5
end as SubCode
from SubCodeReport3
join cte
on n <= rank
Since you know the number of subcodes you can always do this and your question asks how to UNPIVOT: 由于您知道子代码的数量,因此您始终可以执行此操作,并且您的问题询问如何取消注册:
select [ S-ID], [Rank], [AGE], [SchoolCode], [SubCode]
from (select [ S-ID], [Rank], [AGE], [SchoolCode], [SubCode1]
from SubCodeReport3 SCR3
where SCR3.[Rank] = 1) R1
unpivot (SubCode FOR Subject IN (SubCode1)) as unpvt1
UNION ALL
select [ S-ID], [Rank], [AGE], [SchoolCode], [SubCode]
from (select [ S-ID], [Rank], [AGE], [SchoolCode], [SubCode1], [SubCode2]
from SubCodeReport3 SCR3
where SCR3.[Rank] = 2) R1
unpivot (SubCode FOR Subject IN (SubCode1, SubCode2)) as unpvt2
UNION ALL
select [ S-ID], [Rank], [AGE], [SchoolCode], [SubCode]
from (select [ S-ID], [Rank], [AGE], [SchoolCode], [SubCode1], [SubCode2], [SubCode3]
from SubCodeReport3 SCR3
where SCR3.[Rank] = 3) R1
unpivot (SubCode FOR Subject IN (SubCode1, SubCode2, SubCode3)) as unpvt3
UNION ALL
select [ S-ID], [Rank], [AGE], [SchoolCode], [SubCode]
from (select [ S-ID], [Rank], [AGE], [SchoolCode], [SubCode1], [SubCode2], [SubCode3], [SubCode4]
from SubCodeReport3 SCR3
where SCR3.[Rank] = 4) R1
unpivot (SubCode FOR Subject IN (SubCode1, SubCode2, SubCode3, SubCode4)) as unpvt4
UNION ALL
select [ S-ID], [Rank], [AGE], [SchoolCode], [SubCode]
from (select [ S-ID], [Rank], [AGE], [SchoolCode], [SubCode1], [SubCode2], [SubCode3], [SubCode4], [SubCode5]
from SubCodeReport3 SCR3
where SCR3.[Rank] = 5) R1
unpivot (SubCode FOR Subject IN (SubCode1, SubCode2, SubCode3, SubCode4, SubCode5)) as unpvt5
This is what worked for me. 这对我有用。
WITH CodesReportCTE
(
[Number]
,[ S-ID]
,[Rank]
,[AGE]
,[SchoolCode]
,[Code]
)
AS
(
SELECT
ROW_NUMBER() over (PARTITION BY [ S-ID],[SchoolCode] ORDER BY [ S-ID],[SchoolCode]) AS Number
,[ S-ID]
,[Rank]
,[AGE]
,[SchoolCode]
,up.Code [Code]
FROM [dbo].[SubCodeReport3]
UNPIVOT
(
Code
for x in (SubCode1,SubCode2,SubCode3,SubCode4,SubCode5) ) up
WHERE up.Code <> ' '
)
SELECT
--[Number]
--,
[ S-ID]
,[Rank]
,[AGE]
,[SchoolCode]
,[Code]
FROM CodesReportCTE
WHERE Number <= [Rank]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.