sqlserver pivot 動態行轉列多行轉多列


先看效果:

原來的查詢結果

 

 

 想要的效果:

 

 

用到的關鍵函數:  

pivot()   快速實現行轉列

PIVOT(<聚合函數>([聚合列值]) FOR [行轉列前的列名] IN([行轉列后的列名1],[行轉列后的列名2],[行轉列后的列名3],.......[行轉列后的列名N]))

unpivot()  快速實現列傳行 【作為擴展,此次不用】

UNPIVOT([轉換為行的列值在轉換后對應的列名] for [轉換為行的列名在轉換后對應的列名] in ([轉換為行的列1],[轉換為行的列2],[轉換為行的列3],...[轉換為行的列N]))

 

基礎表創建及初始化:

/*==============================================================*/
/* Table: REJECT_NOTIFICATION                                   */
/*==============================================================*/
create table REJECT_NOTIFICATION (
   reject_id            int                  identity,
   admin_id             int                  null,
   table_id             int                  null,
   table_name           nvarchar(50)         null,
   "key"                nvarchar(50)         not null,
   remark               nvarchar(2000)       null,
   create_date          datetime             null,
   constraint PK_REJECT_NOTIFICATION primary key (reject_id)
)
go

insert into REJECT_NOTIFICATION values(1,1,'applications','name','姓名輸入錯誤',getdate())
insert into REJECT_NOTIFICATION values(1,1,'applications','phone','電話輸入錯誤',getdate())
insert into REJECT_NOTIFICATION values(1,1,'applications','address','地址輸入錯誤',getdate())

 

 

首先寫出符合結果的語句:

select max([name]) as [name_remark],max([phone]) as [phone_remark],max([address]) as [address_remark] 
from
(
select [name],[phone],[address] from REJECT_NOTIFICATION a pivot (max(remark) for [key] in ([name],[phone],[address]) ) as pv
where table_id = 1 and table_name = 'Applications'
) s

 

然后觀察規律,將固定格式的語句,變成動態拼接的sql語句,最后通過  exec(@sql)

獲取結果:

declare @event nvarchar(max) = ''
    declare @sql nvarchar(max) = ''
    declare @queryexp nvarchar(max) = ''

    --獲取內層替換變量
    select @event = @event + ',['+[key]+']' 
        from (select distinct [key] from REJECT_NOTIFICATION) a 
        order by [key]

    --獲取外層替換變量
    select @queryexp = @queryexp + ',max(['+[key]+']) as '+'['+[key]+'_remark]' 
        from (select distinct [key] from REJECT_NOTIFICATION) a 
        order by [key]

    --去掉第一個逗號
    select  @queryexp = right(@queryexp,len(@queryexp)-1) 

    --去掉第一個逗號
    select  @event = right(@event,len(@event)-1)
    
    --組裝最后的查詢語句
    set @sql='select '+ @queryexp + ' from( select '+ @event + 'from REJECT_NOTIFICATION a  
    pivot (max(remark) for [key] in ('+ @event + ') 
    ) as pv where table_id = ' + Convert(nvarchar,@table_id) + ' and table_name = ''' + @table_name  + ''') s'
    print @sql
    --執行
    exec(@sql)

 

 

如果要加ID或者其他字段,也可以嘗試下:

比如需要把Table_Id加進來

select max([table_id]) as [table_id],max([name]) as [name_remark],max([phone]) as [phone_remark],max([photo]) as [photo_remark] 
from(
select table_id,[name],[phone],[photo]from REJECT_NOTIFICATION a pivot (max(remark) for [key] in ([name],[phone],[photo]) ) as pv
where table_id = 1 and table_name = 'Applications'
) s

動態寫法,參考上面的例子即可

 

declare @event nvarchar(max) = 'table_id'
    declare @event2 nvarchar(max) = ''
    declare @sql nvarchar(max) = ''
    declare @queryexp nvarchar(max) = 'max([table_id]) as [table_id]'

    --獲取內層替換變量
    select @event = @event + ',['+[key]+']',@event2 = @event2 + ',['+[key]+']'  
        from (select distinct [key] from REJECT_NOTIFICATION) a 
        order by [key]

    --獲取外層替換變量
    select @queryexp = @queryexp + ',max(['+[key]+']) as '+'['+[key]+'_remark]' 
        from (select distinct [key] from REJECT_NOTIFICATION) a 
        order by [key]

    --去掉第一個逗號
    --select  @queryexp = right(@queryexp,len(@queryexp)-1) 

    --去掉第一個逗號
    select  @event2 = right(@event2,len(@event2)-1)
    
    --組裝最后的查詢語句
    set @sql='select '+ @queryexp + ' from( select '+ @event + 'from REJECT_NOTIFICATION a  
    pivot (max(remark) for [key] in ('+ @event2 + ') 
    ) as pv where table_id = ' + Convert(nvarchar,@table_id) + ' and table_name = ''' + @table_name  + ''') s'
    print @sql
    --執行
    exec(@sql)

 

參考:

https://blog.csdn.net/u010892506/article/details/89458862


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM