環境要求: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函式,所以我們需要自己實現 首先建立一組資料 ...