MSSQL 採用pivot函式實現動態行轉列

2021-10-06 16:51:00 字數 4771 閱讀 4420

環境要求:2005+ 在日常需求中經常會有行轉列的事情需求處理,如果不是動態的行,那麼我們可以採取case when 羅列處理。 在sql 2005以前處理動態行或列的時候,通常採用拼接字串的方法處理,在2005以後新增了pivot函式之後,我可以利用這樣函式來處理。 1.

環境要求:2005+

在日常需求中經常會有行轉列的事情需求處理,如果不是動態的行,那麼我們可以採取case when 羅列處理。

在sql 2005以前處理動態行或列的時候,通常採用拼接字串的方法處理,在2005以後新增了pivot函式之後,我可以利用這樣函式來處理。

1.動態sql注入式判斷函式

--既然是用到了動態sql,就有乙個老話題:sql注入。建乙個注入性字元的判斷函式。

create function [dbo].[fn_checksqlinjection]

( @col nvarchar(4000)

)returns bit --如果存在可能的注入字元返回true,反之返回false

asbegin

declare @result bit;

if

upper(@col) like upper(n'%0x%')

or upper(@col) like upper(n'%;%')

or upper(@col) like upper(n'%''%')

or upper(@col) like upper(n'%--%')

or upper(@col) like upper(n'%/*%*/%')

or upper(@col) like upper(n'%exec%')

or upper(@col) like upper(n'%xp_%')

or upper(@col) like upper(n'%sp_%')

or upper(@col) like upper(n'%select%')

or upper(@col) like upper(n'%insert%')

or upper(@col) like upper(n'%update%')

or upper(@col) like upper(n'%delete%')

or upper(@col) like upper(n'%truncate%')

or upper(@col) like upper(n'%create%')

or upper(@col) like upper(n'%alter%')

or upper(@col) like upper(n'%drop%')

set @result=1

else

set @result=0

return @result

endgo

2.需求:

--通過日期查詢幾個表聯合,按照檢驗專案分類,按日期橫向展示

select a.檢驗專案 , convert(char(10),a.日期,120)日期,convert(decimal(18,2),cast((sum(a.測試數量)-sum(a.不良數量)) as decimal(18,2))/sum(測試數量))*100  as 良率 

--into #tempcob

from (select 日期,檢驗專案, 測試數量, 不良數量 from 製程cob成測 union all

select 日期,檢驗專案, 測試數量, 不良數量 from 製程cob外觀 union all

select 日期,檢驗專案,測試數量, 不良數量 from 製程cob綁測 union all

select 送檢日期,'fqc_cob_檢驗',檢驗數量,不合格數量 from 製程fqc_cob_檢驗

) as a

where convert(char(10),日期,120)>='2014-10-01' and convert(char(10),日期,120)<= '2014-10-30'

group by a.檢驗專案,a.日期

3.解決方案:

--抓取資料寫入臨時表#tempcob

select a.檢驗專案 , convert(char(10),a.日期,120)日期,convert(decimal(18,2),cast((sum(a.測試數量)-sum(a.不良數量)) as decimal(18,2))/sum(測試數量))*100 as 良率

into #tempcob

from (select 日期,檢驗專案, 測試數量, 不良數量 from 製程cob成測 union all

select 日期,檢驗專案, 測試數量, 不良數量 from 製程cob外觀 union all

select 日期,檢驗專案,測試數量, 不良數量 from 製程cob綁測 union all

select 送檢日期,'fqc_cob_檢驗',檢驗數量,不合格數量 from 製程fqc_cob_檢驗

) as a

where convert(char(10),日期,120)>='2014-10-01' and convert(char(10),日期,120)<= '2014-10-30'

group by a.檢驗專案,a.日期

--檢視臨時表資料,取分布日期(不重複)

--select 日期 from #tempcob

--select distinct 日期 from #tempcob

declare @sql nvarchar(4000)=n'';

--這裡使用了xml處理來處理類組字串

set @sql=stuff((select n','+quotename(b.日期) from (select distinct 日期 from #tempcob) as b

for xml path('')),1,1,n'');

--加入了xml處理和sql注入預防判斷

if dbo.fn_checksqlinjection(@sql)=0

set @sql='select * from #tempcob pivot (max(良率) for 日期 in ('+@sql+')) as tt'

exec(@sql);

drop table #tempcob

親測**

/*動態行轉列,取得設計清單表及服務費明細並動態彙總分類費用*/

/*select * into #tmp_pms_wzfw

from

(select project_code, treename, totalprice

from pms_mid_design_materials

where treename is not null

--group by project_code, treename

union

select project_code, treename, totalprice

from pms_mid_design_service

where treename is not null

--group by project_code, treename

) p*/

select l.orderstatus, p.project_code, p.treename, p.totalprice, l.twrcnstrctcost, l.roomcnstrctcost, l.fcilicnstrctcost, l.elecindcfee --into #tmp_pms_wzfw

into #tmp_pms_wzfw

from

(select project_code, treename, totalprice

from pms_mid_design_materials

where treename is not null

--group by project_code, treename

union

select project_code, treename, totalprice

from pms_mid_design_service

where treename is not null

--group by project_code, treename

) pleft join crm_order_standard l on project_code = prjid

declare @sql nvarchar(4000)=n'';

--這裡使用了xml處理來處理類組字串

set @sql=stuff((select n'],['+ treename from (select distinct treename from #tmp_pms_wzfw where treename is not null and totalprice > 0) b order by treename for xml path('')),1,2,n'') + ']';

--select @sql

--加入了xml處理和sql注入預防判斷

if dbo.fn_checksqlinjection(@sql)=0

set @sql='select * from (select * from #tmp_pms_wzfw where project_code in (select [專案編碼] from tmp_5gprj)) a pivot (sum(totalprice) for treename in ('+@sql+')) as tt'

exec(@sql);

drop table #tmp_pms_wzfw

MSSQL 採用pivot函式實現動態行轉列

環境要求 2005 在日常需求中常常會有行轉列的事情需求處理。假設不是動態的行,那麼我們能夠採取case when 羅列處理。在sql 2005曾經處理動態行或列的時候,通常採用拼接字串的方法處理。在2005以後新增了pivot函式之後,我能夠利用這樣函式來處理。1.動態sql注入式推斷函式 既然是...

PIVOT函式,行轉列

pivot函式的格式如下 pivot 聚合函式 聚合列值 for 行轉列前的列名 in 行轉列後的列名1 行轉列後的列名2 行轉列後的列名3 行轉列後的列名n select from shoppingcart as c pivot count totalprice for week in 1 2 3...

HIVE實現pivot函式

pivot是乙個非常實用的函式 pivot的格式 select 原表字段1,2,3 from 表名 as 原表別名 pivot 聚合函式 原表字段1 for 原表字段2 in 原表2值1 原表字段2值2 as 新錶別名 但是hive裡面沒有自帶pivot函式,所以我們需要自己實現 首先建立一組資料 ...