带条件的SQL Pivot查询

时间:2018-07-11 20:46:43

标签: sql-server pivot

我正在尝试使用SQL Pivot将行转换为列。

这是我的table结构

=====================
ID  CODE    CODE_TYPE        
=====================
1   C1          D
1   C2          D
1   C3          D
1   C4          D
1   C5          D
1   C6          D
1   C7          D
1   C8          D
1   C9          D
1   C10         D
1   C11         P
1   C12         P
1   C13         P   
1   C14         P   
1   C15         P   
1   C16         P
1   C17         P
1   C18         P
1   C19         P
1   C20         P

我想基于CODE

CODE_TYPE值转换为以下格式的列
==================================================================================================================================================================
ID  CODE1   CODE2   CODE3   CODE4   CODE5   CODE6   CODE7   CODE8   CODE9   CODE10  CODE11  CODE12  CODE13  CODE14  CODE15  CODE16  CODE17  CODE18  CODE19  CODE20
==================================================================================================================================================================   
1   C1      C2      C3      C4      C5      C6      C7      C8      C9      C10     C11     C12     C13     C14     C15     C16     C17     C18     C19     C20

我有以下SQL query

SELECT  PIV.ID,
        PIV.[CODE1],
        PIV.[CODE2],
        PIV.[CODE3],
        PIV.[CODE4],
        PIV.[CODE5],
        PIV.[CODE6],
        PIV.[CODE7],
        PIV.[CODE8],
        PIV.[CODE9],
        PIV.[CODE10]
FROM (

            SELECT          
                    C.ID,
                    C.CODE,
                    ROW_NUMBER() OVER (PARTITION BY C.ID  ORDER BY C.ID) AS 'CODE_NO' 
            FROM    CODE_TABLE C 
            WHERE C.CODE_TYPE='D'
        ) T1
PIVOT   (
            MAX(T1.CODE) 
            FOR T1.CODE_NO IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])
        ) PIV

我坚持过滤CODE_TYPE='P'。 所有CODE_TYPE='P'都应从[11]-[20]填充

有人可以帮我吗?

谢谢

2 个答案:

答案 0 :(得分:1)

您可以为此使用条件聚合。

declare @Something table
(
    ID int
    , CODE varchar(10)
    , CODE_TYPE char(1)
)

insert @Something values
(1, 'C1', 'D')
, (1, 'C2', 'D')
, (1, 'C3', 'D')
, (1, 'C4', 'D')
, (1, 'C5', 'D')
, (1, 'C6', 'D')
, (1, 'C7', 'D')
, (1, 'C8', 'D')
, (1, 'C9', 'D')
, (1, 'C10', 'D')
, (1, 'C11', 'P')
, (1, 'C12', 'P')
, (1, 'C13', 'P')   
, (1, 'C14', 'P')   
, (1, 'C15', 'P')   
, (1, 'C16', 'P')
, (1, 'C17', 'P')
, (1, 'C18', 'P')
, (1, 'C19', 'P')
, (1, 'C20', 'P')
;
with SortedValues as
(
    select RowNum = ROW_NUMBER() over(partition by ID order by CODE_TYPE, CODE)
        , *
    from @Something
)

select ID
    , max(case when RowNum = 1 AND CODE_TYPE = 'D'  then CODE end) as CODE1
, max (case when RowNum = 2 AND CODE_TYPE = 'D' then CODE end) as CODE2
, max(case when RowNum = 3 AND CODE_TYPE = 'D' then CODE end) as CODE3
, max(case when RowNum = 4 AND CODE_TYPE = 'D' then CODE end) as CODE4
, max(case when RowNum = 5 AND CODE_TYPE = 'D' then CODE end) as CODE5
, max(case when RowNum = 6 AND CODE_TYPE = 'D' then CODE end) as CODE6
, max(case when RowNum = 7 AND CODE_TYPE = 'D' then CODE end) as CODE7
, max(case when RowNum = 8 AND CODE_TYPE = 'D' then CODE end) as CODE8
, max(case when RowNum = 9 AND CODE_TYPE = 'D' then CODE end) as CODE9
, max(case when RowNum = 10 AND CODE_TYPE = 'P' then CODE end) as CODE10
, max(case when RowNum = 11 AND CODE_TYPE = 'P' then CODE end) as CODE11
, max(case when RowNum = 12 AND CODE_TYPE = 'P' then CODE end) as CODE12
, max(case when RowNum = 13 AND CODE_TYPE = 'P' then CODE end) as CODE13
, max(case when RowNum = 14 AND CODE_TYPE = 'P' then CODE end) as CODE14
, max(case when RowNum = 15 AND CODE_TYPE = 'P' then CODE end) as CODE15
, max(case when RowNum = 16 AND CODE_TYPE = 'P' then CODE end) as CODE16
, max(case when RowNum = 17 AND CODE_TYPE = 'P' then CODE end) as CODE17
, max(case when RowNum = 18 AND CODE_TYPE = 'P' then CODE end) as CODE18
, max(case when RowNum = 19 AND CODE_TYPE = 'P' then CODE end) as CODE19
, max(case when RowNum = 20 AND CODE_TYPE = 'P' then CODE end) as CODE20
from SortedValues
group by ID

答案 1 :(得分:1)

这是一个动态的枢轴示例。

DECLARE @code_type char(1) = 'P'

DECLARE @sql NVARCHAR(MAX)
SELECT @sql = '

SELECT  PIV.ID, ' + 
(
    SELECT STUFF(
    (
        SELECT ',' + QUOTENAME('CODE' + REPLACE(CODE, 'C', '')) 
        FROM CodeTable 
        WHERE CODE_TYPE = @code_type 
        FOR XML PATH('')
    ), 1, 1, '')
) + '
FROM (    
        SELECT          
            C.ID,
            C.CODE,
            ''CODE'' + REPLACE(CODE, ''C'', '''') AS ''CODE_NO'' 
            FROM    CodeTable C 
            WHERE C.CODE_TYPE= ''' + @code_type + '''
        ) T1
PIVOT   (
            MAX(T1.CODE) 
            FOR T1.CODE_NO IN (' + 
            (
                SELECT STUFF(
                (
                    SELECT ',' + QUOTENAME('CODE' + REPLACE(CODE, 'C', '')) 
                    FROM CodeTable 
                    WHERE CODE_TYPE = @code_type 
                    FOR XML PATH('')
                    ), 1, 1, '')
                ) + ')
        ) PIV'

EXEC sp_executesql @sql

返回:

ID  CODE11  CODE12  CODE13  CODE14  CODE15  CODE16  CODE17  CODE18  CODE19  CODE20
1   C11     C12     C13     C14     C15     C16     C17     C18     C19     C20