条件逆轴 SQL table
Conditional Unpivot SQL table
我有一个 table,看起来像这样 <SubCodeReport3>
,它有一个名为 Rank
的列。对于每一行,我需要什么是排名,并根据该值我需要取消透视 SubCode 列(SubCode1、SubCode2 和 Subcode3 等)并将它们转换为行。
如上所示
Rank 2 Subcode1 & SubCode2 已被取消透视
等级 1 SubCode1 已被取消透视
等级 3 Subcode1、Subcode2 和 SubCode3 已取消透视。
不会出现Rank高于no的情况。可用的 SubCode 列。有任何想法吗?
光标遍历行?
这里有一些 SQL 来创建这个示例 table
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'')
从 CTE 或派生的 table 开始,对 table 进行完整的逆轴旋转,然后添加分区的 row_number,以便对于原始 [=19= 中的每一行], SubCode1 将在 row_number 1 上,SubCode2 将在 row_number 2 上,等等
然后 select 来自 row_number 小于或等于 [Rank] 的 CTE。
您需要 CROSS JOIN 到 table 序列号:
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
既然你知道子代码的数量,你总是可以这样做,你的问题是如何 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
这对我有用。
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]
我有一个 table,看起来像这样 <SubCodeReport3>
,它有一个名为 Rank
的列。对于每一行,我需要什么是排名,并根据该值我需要取消透视 SubCode 列(SubCode1、SubCode2 和 Subcode3 等)并将它们转换为行。
如上所示 Rank 2 Subcode1 & SubCode2 已被取消透视 等级 1 SubCode1 已被取消透视 等级 3 Subcode1、Subcode2 和 SubCode3 已取消透视。
不会出现Rank高于no的情况。可用的 SubCode 列。有任何想法吗?
光标遍历行?
这里有一些 SQL 来创建这个示例 table
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'')
从 CTE 或派生的 table 开始,对 table 进行完整的逆轴旋转,然后添加分区的 row_number,以便对于原始 [=19= 中的每一行], SubCode1 将在 row_number 1 上,SubCode2 将在 row_number 2 上,等等
然后 select 来自 row_number 小于或等于 [Rank] 的 CTE。
您需要 CROSS JOIN 到 table 序列号:
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
既然你知道子代码的数量,你总是可以这样做,你的问题是如何 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
这对我有用。
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]