SQL Server中的Pivoting,动态列

时间:2015-07-30 11:41:06

标签: sql sql-server

我有像这样的表

贷款计划

Id  Name       
------------   
1   LP1        
2   LP2        
3   LP3        

频道

Id  Name
----------
4  Channel1
5  Channel2
6  Channel3

LoanProgramsChannels

LoanProgramId      Channelid  
----------------------
1                   4
1                   5
2                   4

我想获得这些数据

LoanProgarmNames   channel1 channel2  channel3
----------------   -------- --------  --------
LP1                 y            y       N
LP2                 y            N       N
LP3                 N            N       N

我对SQL很新,我知道我必须使用PIVOT来实现这些,但不确定如何在这些场景中实现。有人可以提供帮助吗?

2 个答案:

答案 0 :(得分:0)

因为你需要填补空白"最好的方法是使用CROSS JOIN

创建笛卡尔积
;WITH CTE AS (
SELECT A.NAME AS LOANPROGRAMNAME 
, B.NAME AS CHANNELNAME
, CASE WHEN C.CHANNELID IS NULL THEN 'N' ELSE 'Y' END AS LOANPROGRAMCHANNELS
FROM LOANPROGRAMS AS A
CROSS JOIN CHANNELS AS B
LEFT JOIN LOANPROGRAMSCHANNELS AS C
ON CAST(A.ID AS VARCHAR)+CAST(B.ID AS VARCHAR) = 
CAST(C.LOANPROGRAMID AS VARCHAR)+CAST(C.CHANNELID AS VARCHAR))
SELECT LOANPROGRAMNAME, [CHANNEL1], [CHANNEL2], [CHANNEL3]
FROM CTE
PIVOT(MAX(LOANPROGRAMCHANNELS) FOR CHANNELNAME IN ([CHANNEL1], [CHANNEL2], [CHANNEL3])) PIV

一旦您获得了条件(Y / N),您就可以转动所需的列,如此处所示。

答案 1 :(得分:0)

可能有更好的方法对此进行编码,但我相信以下内容将提供您想要的内容:

declare @tbLoanPrograms table (
    ID int, Name varchar(12)
)

insert into @tbLoanPrograms (
    ID      , Name
)
values    (1, 'LP1')
        , (2, 'LP2')
        , (3, 'LP3')

declare @tbChannels table (
    ID int, Name varchar(12)
)

insert into @tbChannels (
    ID      , Name
)
values    (4, 'Channel1')
        , (5, 'Channel2')
        , (6, 'Channel3')

declare @tbLoanProgramsChannels  table (
    LoanProgramId int, Channelid int
)

insert into @tbLoanProgramsChannels (
    LoanProgramId      , Channelid
)
values    (1, 4)
        , (1, 5)
        , (2, 4)

select
    t.Name
    , Channel1 = max(Channel1)
    , Channel2 = max(Channel2)
    , Channel3 = max(Channel3)
from (
    select
        lp.Name
        , Channel1 =
                case
                when lpc.LoanProgramId is not null and lpc.Channelid = 4
                    then 'y'
                else 'N'
            end
        , Channel2 =
            case
                when lpc.LoanProgramId is not null and lpc.Channelid = 5
                    then 'y'
                else 'N'
            end
        , Channel3 =
            case
                when lpc.LoanProgramId is not null and lpc.Channelid = 6
                    then 'y'
                else 'N'
            end
    from
        @tbLoanPrograms lp
        left join @tbLoanProgramsChannels lpc on lpc.LoanProgramId = lp.ID
        left join @tbChannels c on c.ID = lpc.Channelid
) t
group by t.Name