SQL实现交叉表的方法(补)

上一篇转帖过来后,实际运行了一下不好使,QTY必须定义。粗略看了下源码,可能作者图省事,传入的T4参数没有转换成dicimal型,直接杜撰了个QTY变量,自然报错。(或者转帖的就不是原帖,很有可能!),记得邹建有一个存储过程的,找了一下,果然找到,而且执行成功。在这里记录一下。非常感谢邹建大哥的东东,真帮了大忙了。代码如下

if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[dbo].[p_qry]')   and   OBJECTPROPERTY(id,   N'IsProcedure')   =   1) 
  drop   procedure   [dbo].[p_CrossTable] 
  GO 
  /*--生成交叉表的简单通用存储过程 
    根据指定的表名,纵横字段,统计字段,自动生成交叉表 
    并可根据需要生成纵横两个方向的合计 
    注意,横向字段数目如果大于纵向字段数目,将自动交换纵横字段 
    如果不要此功能,则去掉交换处理部分 
  --邹建   204.06--*/ 
  /*--调用示例 
    exec   p_qry   'syscolumns','id','colid','colid',1,1 
  --*/ 
  create   proc   p_CrossTable 
  @TableName   sysname,   --表名 
  @RowField   sysname,     --交叉表最左面的列 
  @ColumnField   sysname,     --交叉表最上面的列 
  @DataField   sysname,   --交叉表的数数据字段 
  @IsColumnSum   bit,--为1时在交叉表横向最右边加横向合计 
  @IsRowSum   bit   --为1时在交叉表纵向最下边加纵向合计 
  as 
  declare   @s   nvarchar(4000),@sql   varchar(8000) 
  --判断横向字段是否大于纵向字段数目,如果是,则交换纵横字段 
  /*
  set   @s='declare   @a   sysname 
  if(select   case   when   count(distinct   ['+@RowField+'])<count(distinct   ['+@ColumnField+'])   then   1   else   0   end 
  from   ['+@TableName+'])=1 
    select   @a=@RowField,@RowField=@ColumnField,@ColumnField=@a' 
  exec   sp_executesql   @s 
    ,N'@RowField   sysname   out,@ColumnField   sysname   out' 
    ,@RowField   out,@ColumnField   out 
   */
  --生成交叉表处理语句 
  set   @s=' 
  set   @s='''' 
  select   @s=@s+'',[''+cast(['+@ColumnField+']   as   varchar)+'']=sum(case   ['+@ColumnField 
    +']   when   ''''''+cast(['+@ColumnField+']   as   varchar)+''''''   then   ['+@DataField+']   else   0   end)'' 
  from   ['+@TableName+'] 
  group   by   ['+@ColumnField+']' 
  exec   sp_executesql   @s 
    ,N'@s   varchar(8000)   out' 
    ,@sql   out 
  --是否生成合计字段的处理 
  declare   @sum1   varchar(200),@sum2   varchar(200),@sum3   varchar(200) 
  select   @sum1=case   @IsColumnSum   
      when   1   then   ',[合计]=sum(['+@DataField+'])' 
      else   ''   end 
    ,@sum2=case   @IsRowSum   
      when   1   then   '['+@RowField+']=case   grouping([' 
        +@RowField+'])   when   1   then   ''合计''   else   cast([' 
        +@RowField+']   as   varchar)   end' 
      else   '['+@RowField+']'   end 
    ,@sum3=case   @IsRowSum 
      when   1   then   '   with   rollup' 
      else   ''   end 
  --生成交叉表 
  exec('select   '+@sum2+@sql+@sum1+' 
  from   ['+@TableName+'] 
  group   by   ['+@RowField+']'+@sum3) 
  go 

 

再次感谢!

posted @ 2009-12-08 12:38  Rambo'Ma  阅读(571)  评论(0编辑  收藏  举报