交叉表自动生成(修改版)

[ 756 查看 / 0 回复 ]

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