您的位置:首页 > 数据库

sqlserver下通用 行转列 函数(原创)

2013-10-11 18:31 239 查看
因项目中常需要行转列的统计报表,每次编写时,均费一番功夫,今天特地花费几个小时编写了一套用于Sqlserver的 通用行转列 存储过程

采用sqlserver2000自带的pubs示例库,实验目标:

将作者所写的图书价格 以横向表格展示 如:

作者书名1书名2书名3书名4
张三25.03.5  
李四  89.054.30
1>首先查询出作者对应的书名以及价格

Sql语句如下

select a.au_lname,c.title ascolName,cast(price asnvarchar(50)) asresult
from authors a ,titleauthor b,titles c
where a.au_id = b.au_id and c.title_id= b.title_id



如图所示:






.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

2>只需将sql语句放入存储过程参数即可:

declare @temp nvarchar(500)
set @temp = 'select a.au_lname as作者,c.title ascolName,cast(price asnvarchar(50)) asresult
from authors a ,titleauthor b,titles c
where a.au_id = b.au_id and c.title_id= b.title_id '
exec CommonRowToCol  @temp


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

执行效果





3>使用时,只需将要作为列名的字段定义为colname,将欲显示的列定义为result即可

 

完整的存储过程代码如下:

create procedure dbo.CommonRowToCol


[code]@sql nvarchar(4000)


as


begin


--必须包含colname列和result列(不区分大小写),


--除colname列和result列 其余各列均会作为判别记录唯一性的条件


 


create table #temp([序号] int IDENTITY(1,1))


declare @sqlTemp nvarchar(4000),@sql_select nvarchar(1000),@temp nvarchar(500)


declare @sql_All nvarchar(4000),@sql_Table nvarchar(1000),@sql_declare nvarchar(1000),@sql_Fetch nvarchar(1000) ,


@sql_id nvarchar(1000),@sql_id2 nvarchar(1000),@sql_insert nvarchar(1000),@sql_value nvarchar(1000)


 


set @sql_select = '' set @sql_All = '' set @sql_Table ='' set @sql_declare = '' set @sql_Fetch = ''


set @sql_id = '' set @sql_id2 = '' set @sql_insert='' set @sql_value = ''




set @sql = lower(LTRIM(@sql))


set @sqlTemp = @sql


set @sqlTemp = ' select top 0 * into #tempTbl from ('+@sqlTemp+')z '+


' select @temp =  Name+'',''+@temp from ( select top 1111 name from tempdb..syscolumns where id = object_id(N''tempdb..#tempTbl'') order by colorder )z '


EXECUTE sp_executesql @sqlTemp, N'@temp nvarchar(1000) output',@sql_select output


 


while charindex(',',@sql_select) > 0 


begin


select @temp = lower(LEFT(@sql_select,charindex(',',@sql_select)-1))


select @sql_select = stuff(@sql_select,1,charindex(',',@sql_select),'')




if (@temp <> 'colname') and (@temp<>'result')


begin


set @sql_Table = ' ['+@temp+'] nvarchar(1000),' + @sql_Table 


set @sql_insert = ' ['+@temp+'],' + @sql_insert 


set @sql_value ='isnull(@'+@temp+',''''),'+@sql_value 


set @sql_id =  ' ['+@temp+'] =  isnull(@'+@temp+','''') and' + @sql_id


set @sql_id2 = ' ['+@temp+'] =  isnull(''''''+@'+@temp+'+'''''' ,'''''''') and' + @sql_id2


end;


set @sql_declare = ' @'+@temp+' nvarchar(1000),'+@sql_declare 


set @sql_Fetch = ' @'+@temp+','+@sql_Fetch 


end;


set @sql_Table = 'ALTER TABLE #temp ADD ' +left(@sql_Table,len(@sql_table)-1)+' '


set @sql_declare = 'declare @sqlTemp nvarchar(4000),' +left(@sql_declare,len(@sql_declare)-1) + ' '


set @sql_Fetch = left(@sql_Fetch,len(@sql_fetch)-1) + ' '


set @sql_id = left(@sql_id,len(@sql_id)-3) + ' '


set @sql_id2 = left(@sql_id2,len(@sql_id2)-3) + ' '


set @sql_insert = left(@sql_insert,len(@sql_insert)-1) + ' '


set @sql_value = left(@sql_value,len(@sql_value)-1) + ' '


 


set @sql_All = @sql_declare + 


' Declare myCur Cursor   For '+ @sql + ' Open myCur Fetch NEXT From myCur Into '+ @sql_Fetch+


' While @@fetch_status=0 Begin '+


'   if not exists(select * from tempdb..syscolumns where id = object_id(N''tempdb..#temp'') and name = @colName)


begin


set @sqlTemp =''alter table #temp add [''+@colName+''] nvarchar(4000) ''


exec(@sqlTemp)


end 


if not exists(select * from #temp where '+@sql_id+')


begin


insert into #temp('+@sql_insert+') values('+@sql_value+')


end 




set @sqlTemp ='' update #temp set [''+@colName+''] = isnull(''''''+@result+'''''','''''''') where ' + @sql_id2+''' 


exec(@sqlTemp)




Fetch NEXT From myCur Into '+ @sql_Fetch+


'end 


Close myCur 


Deallocate myCur 


select * from #temp


'




exec (@sql_Table)


exec(@sql_All)


end

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

4>以上代码在sqlserver2000,2005,2008测试通过.

5>交流请留言,转载请标注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: