如何生成交叉表?

http://blog.csdn.net/demongz/archive/2005/03/22/327169.aspx

在关系数据库中,经常为了使数据库更符合第三范式,同时也是从数据存取速度和空间使用率来考虑。在数据结构设计的时候,会尽量减少记录长度。而且有时候为了使程序尽量通用化和产品化,通过用户个性化设置数据来满足信息的多样化需求。但是体现给最终用户是要求能直观的报表形式,所以,就要用到交叉表的技术,笔者这里有一段代码,非常有用,希望能给大家带来方便。

CREATE   PROCEDURE CrossTable --交叉表生成器
--(Select Distinct SuppCode As SCode,MCode,PurQtyRate As Rate
--        From MtSPM A Inner Join MtSPD B On A.ID=B.MtSuppPriceM_ID
--                     Inner Join Suppliers C On A.Supp_ID=C.ID
--        Where A.Active_KID=120 And AduitPass=1) D
@vSourceTAB As Varchar(2000), --数据来源表,可以为表,视图,或者SQL语句(要用括号以及别名:如上注释段)
@vGroupbyField As Varchar(50), --被selct Group By 要显示出来的,可以多个字段(记录可以有空值)
@vTransFormCol As Varchar(50), --交叉表中的合计等函数计算值的字段
@vFunction As Varchar(50)=' Sum', --默认值,交叉表中的函数,也可以是' 2*Sum'的计算公式
@vPivotCol As Varchar(50), --要转换成列的字段,唯一列,可以是表达式'Field1+Field2'(记录可以有空值)
@vStrWhere As Varchar(500) =Null --Where 约束条件,可以为空
AS
--重要提示:@StrSql的Largest size allowed Is 8000,因此尽量将少的字段内容转换为列
Declare @StrSql As Varchar(8000) --//总的SQL语句
Declare @StrSum As Varchar(3000) --//列合计
Declare @pCols As Varchar(100)
Declare @StrWhere As Varchar(500)
Execute('Declare CursorCross Cursor For 
          Select Distinct ' + @vPivotCol + ' From ' +@vSourceTAB +' Order By ' + @vPivotCol + ' For Read only ')
Begin
  Set Nocount On
  Set @StrSql =''
  Set @StrSum=''
  Set @pCols=''
  IF Rtrim(Ltrim(IsNull(@vStrWhere,''))) <> ''
  Begin
    Set @StrWhere=' Where ' + @vStrWhere + ' '
  End
Else
  Set @StrWhere=''
  Open CursorCross
  While (0=0)
  Begin
    Fetch Next From CursorCross Into @pCols
    IF (@@Fetch_Status<>0) Break
    IF @pCols Is  Null --//不为空值,
    Set @pCols='Null'
    --为了防止新创建的列的标题名称,与@vGroupbyField中的字段重名,
    --新创建的列的标题名称都增加前缀[@vGroupbyField.新创建的列的标题名称]
--因Sql长度限制Max=8000,由源数据控制字段值不能为Null,因此这里不再检验值是否为Null
    Set @StrSql=@StrSql +',' + @vFunction +
        '(Case '+@vPivotCol+' When ' + @pCols+ ' Then '+@vTransFormCol +' Else Null End) As '+
        '['+Left(@vPivotCol,1)+@pCols+']'
--因长度限制,不计算列间之和
  Set @StrSum=@StrSum + '+IsNull(A.' + '['+Left(@vPivotCol,1)+@pCols+']' +',0)'
  End
  Set  @StrSql = ' Select ' + @vGroupByField + ' ' +@StrSql + ' From ' +@vSourceTAB+ ' ' + @StrWhere +
                 ' Group By ' + @vGroupByField
  --列向合计 为字段名'TotalSum'
  Set @StrSql ='Select A.*,(0' +@StrSum + ') As TotalSum From (' + @StrSql  +') As A'
  Set @StrSql ='Select A.* From ('+@StrSql+') As A'
  Execute(@StrSql)
  Close CursorCross
  Deallocate CursorCross
End

--CrossTable 'THCLD','storeid,dh','Qty','SUM','GoodsCode',''

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值