zoukankan      html  css  js  c++  java
  • sqlserver下通用 行转列 函数(原创)

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

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

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

    作者 书名1 书名2 书名3 书名4
    张三 25.0 3.5    
    李四     89.0 54.30

    1>首先查询出作者对应的书名以及价格

    Sql语句如下

    select a.au_lname,c.title as colName,cast(price as nvarchar(50)) as result
    from authors a ,titleauthor b,titles c
    where a.au_id = b.au_id and c.title_id= b.title_id
    如图所示:

    @YEZVR}Y@]`AXU{`A$)_E$G

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

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

    执行效果

    QQ图片20131011182343

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

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

    create procedure dbo.CommonRowToCol
        @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

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

    5>交流请留言,转载请标注

  • 相关阅读:
    有关Angular 2.0的一切
    后Angular时代二三事
    构建单页Web应用
    用JS渲染的单页面应用其实性能还是比较差的
    给一位打算从事前端,但是又有疑惑的在校大学生的回信
    企业文化与价值观 — 给新员工的一封信
    老码农的技术理想
    (OK) install vmware12 in fedora23
    ECMAScript——wikipedia
    《ECMAScript 6入门》——JavaScript
  • 原文地址:https://www.cnblogs.com/yaoshi641/p/3364004.html
Copyright © 2011-2022 走看看