sql server 縱向表橫向輸出的實現

2021-05-25 10:05:54 字數 4280 閱讀 9416

有時候,我們經常需要通過縱向儲存的資料,在做報表的時候,橫向輸出顯示出來。

最典型的例子:

問卷系統中的儲存答案的表,儲存的資料類似於(儲存形式):

c_userid (使用者編號)c_questionid(問題編號)c_item(答案)

11a12

b1 3c

1 4 d

21d22d

2 3a

2 4b

以上表中儲存了倆個使用者的答題資訊。

但是我們可能需要在做報表的時候,需要輸出類似於這樣的資訊(輸出形式):

c_userid (使用者編號)  q1(問題編號1)q2(問題編號2)q3(問題編號3)q4(問題編號4)

1abcd

2ddab

我們需要借組 sql server2005 中的pivot 函式+聚合函式來實現,但是,這個函式,個人感覺還是不是太靈活(呵呵 ,本人有點菜),所以,寫了乙個儲存過程來對這個pivot 函式的轉換列進行了封裝。呼叫起來很方便,自動獲取縱向表中相同行的最大值,不會當心遺漏某些行。

下面是原始碼(在這個儲存過程中,使用了中間表,估計會有效率問題,希望大蝦們不吝賜教):

/**

* 翻轉表(縱向表橫向輸出)

*/if exists(select * from sysobjects where name='proc_pivot_table')

drop proc proc_pivot_table

gocreate proc proc_pivot_table

@table varchar(50) --表名

,@columname varchar(50) --要橫向顯示的欄位名 答案

,@columkeyitem varchar(50) --要橫向顯示的欄位名的key欄位名 問題編號

,@keycolumitem varchar(50) --橫向顯示的key欄位名 使用者編號

,@columasname varchar(50)=null --key指定別名(要橫向顯示的字段列名稱)

asbegin

--設定要橫向顯示的字段列名稱,如果沒有設定,則預設取「要橫向顯示的欄位名」作為列名稱

if (@columasname is null) set @columasname=@columname

declare @maxcolums int

exec('if exists( select * from sysobjects where name=''temp_t1'') 

drop table temp_t1 ')

exec (' select top 1 count(convert(varchar(max),'+@columname+')) as c_itemsnum 

into temp_t1  from '+@table+'  group by '+@keycolumitem+' order by c_itemsnum desc')

select @maxcolums=c_itemsnum from temp_t1

print @maxcolums

declare @i int,@sql varchar(8000),@filds varchar(8000)

set @i=1

--拼接sql

set @sql='select '+@keycolumitem+' '

--開始拼接查詢字段

set @filds=''

while(@i<=@maxcolums)

begin

set @filds=@filds+' , ['+convert(varchar(5),@i)+']'

set @sql=@sql+' , max(['+convert(varchar(5),@i)+']) as '+@columasname+convert(varchar(5),@i)+' '

set @i=@i+1

end--開始轉置

set @sql=@sql+' from '+@table+' pivot (max('+@columname+')for '+@columkeyitem+' in

( [0] '+@filds+')) as pvt group by '+@keycolumitem

print @sql

exec(@sql)

endgo

下面是測試用例

* 構造用利

if exists(select * from sysobjects where name='t_answer_test')

drop table t_answer_test

gocreate table t_answer_test(

c_id int identity(1,1) not null, --序號

c_userid int, --使用者編號

c_questionid int, --問題編號

c_item nvarchar(max) --答案

goinsert into t_answer_test(c_userid,c_questionid,c_item) values('1','1','a')

insert into t_answer_test(c_userid,c_questionid,c_item) values('1','2','a')

insert into t_answer_test(c_userid,c_questionid,c_item) values('1','3','b')

insert into t_answer_test(c_userid,c_questionid,c_item) values('1','4','c')

insert into t_answer_test(c_userid,c_questionid,c_item) values('1','5','d')

insert into t_answer_test(c_userid,c_questionid,c_item) values('1','6','a')

insert into t_answer_test(c_userid,c_questionid,c_item) values('2','1','d')

insert into t_answer_test(c_userid,c_questionid,c_item) values('2','2','')

insert into t_answer_test(c_userid,c_questionid,c_item) values('3','1','a')

insert into t_answer_test(c_userid,c_questionid,c_item) values('3','2','b')

insert into t_answer_test(c_userid,c_questionid,c_item) values('3','3','')

insert into t_answer_test(c_userid,c_questionid,c_item) values('3','4','d')

insert into t_answer_test(c_userid,c_questionid,c_item) values('3','5','d')

insert into t_answer_test(c_userid,c_questionid,c_item) values('3','6','')

* 測試

declare 

@table varchar(50) --表名

,@columname varchar(50) --要橫向顯示的欄位名 答案

,@columkeyitem varchar(50) --要橫向顯示的欄位名的key欄位名 問題編號

,@keycolumitem varchar(50) --橫向顯示的key欄位名 使用者編號

,@columasname varchar(50) --key指定別名

set @table='t_answer_test'--答案表名稱

set @columname='c_item'--選項

set @keycolumitem='c_userid'--使用者編號

set @columkeyitem='c_questionid'--問題編號

set @columasname='q'--問題別名

--顯示原始資料

select c_userid,c_questionid,c_item from t_answer_test

--橫向輸出資料

exec proc_pivot_table @table,@columname,@columkeyitem,@keycolumitem,@columasname

這裡曬出來sql原始碼:

縱向表橫向輸出資料.sql

mysql橫向轉縱向 縱向轉橫向排列的方法

初始化資料 程式設計客棧 drop table if exists test 01 create table test 01 id int 0 not null,user varchar 255 character set utf8mb4 collate utf8mb4 0900 ai ci nul...

橫向越權與縱向越權

橫向越權 橫向越權指的是攻擊者嘗試訪問與他擁有相同許可權的使用者的資源 縱向越權 縱向越權指的是乙個低級別攻擊者嘗試訪問高階別使用者的資源 如何防止橫向越權漏洞 可通過建立使用者和可操作資源的繫結關係,使用者對任何資源進行操作時,通過該繫結關係確保該資源是屬於該使用者所有的。對請求中的關鍵引數進行間...

在Oracle中採用縱向和橫向結構表

在本文中,我將分析 關係 資料庫中組織資料的不同方式,在本文的例子中,我採用oracle進行闡述,但其他關聯式資料庫面臨同樣的問題,這些關聯式資料庫組織資料的方式既有優點也有缺點,將給以區分,據此讀者可判定適合他們的需要資料組織方式。採用何種資料組織方式,取決於業務需求和開發需要,各種儲存資料的方式...