2015-10-06 63 views
1

我有一个表,看起来像这样<SubCodeReport3>其中有一列叫做Rank。对于每一行我需要什么是排名和基于这个值我需要不透明SubCode列(SubCode1,SubCode2 & Subcode3等),并将它们转换成行。有条件的Unpivot SQL表

enter image description here

如上所见用于 秩2个Subcode1 & SubCode2一直未枢转 等级1 SubCode1一直未枢转 秩3 Subcode1,Subcode2 & SubCode3一直未枢转。

不会出现排名高于排名的情况。可用的SubCode列。有任何想法吗?

游标尽管行吗?

下面是一些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'') 
+0

等级列的样本数据与问题不对应,您说等级不会大于列数,但有值867和更高。 – domenicr

+0

更正了代码 – ZeExplorer

回答

0

开始的CTE或派生表,做表的完全逆转置,并增加了一个分区ROW_NUMBER从而使各行中的原始表,子代码1将在行号1上,子代码2在行号2上等。

然后从该CTE中选择row_number小于或等于[Rank]的位置。

+0

我会试一试,谢谢。 – ZeExplorer

+0

这看起来很优雅,适合我。 – ZeExplorer

0

您需要CROSS JOIN与序列号表:

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 

Fiddle

0

既然你知道子码你总是可以做到这一点的号码和你的问题是问如何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 

See fiddle

0

这对我来说很有用。

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]