最近正好要用到sql的交叉表

最近正好要用到sql的交叉表,
一搜,正好找到前輩01年就做好了的好東西
http://www.delphibbs.com/delphibbs/dispq.asp?lid=679161
(源作Robin_Fang)
我又在此基礎上改了些東西,減少了出錯和一點點增強(主要是解決了日期型字段的出錯問題)

現全部貼出來共享



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(100), --被selct Group By 要顯示出來的,可以多個字段(記錄可以有空值)
@vTransFormCol As Varchar(50), --交叉表中的合計等函數計算值的字段
@vFunction As Varchar(100)=' Sum', --默認值,交叉表中的函數,也可以是' 2*Sum'的計算公式
@vPivotCol As Varchar(100), --要轉換成列的字段,唯一列,可以是表達式'Field1+Field2'(記錄可以有空值)
@vStrWhere As Varchar(1000) =Null, --Where 約束條件,可以爲空
@vGroupbyFieldName As Varchar(50)=null --如果GroupField是表達式,則這裏一定要指定名稱,不然會出錯
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)

if @vGroupbyFieldName is null
set @vGroupbyFieldName=@vGroupbyField

set @strsql=' Declare CursorCross Cursor For  
          Select Distinct ' + @vPivotCol + ' From ' +@vSourceTAB +' Order By ' + @vPivotCol + ' For Read only '
Print @StrSql
Execute(@StrSql)
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 +' AS '+@vGroupbyFieldName+ ' ' +@StrSql + ' From ' +@vSourceTAB+ ' ' + @StrWhere +
                 ' Group By ' + @vGroupByField
  --列向合計 爲字段名'TotalSum',合計方法改爲重新從源表中取值,減少SQL的字符量
  Set @StrSql ='Select A.*,(select '+
               @vFunction+'(' +@vTransFormCol +') from '+ @vSourceTAB+@StrWhere+' Group by '+@vGroupbyField+ ' having '+@vGroupbyField+'=A.'+@vGroupbyFieldName
               +') As TotalSum From (' + @StrSql  +') As A'
  Set @StrSql ='Select A.* From ('+@StrSql+') As A  Order By '+@vGroupByFieldName
  Print @StrSql
  Execute(@StrSql)
  IF @@Error <>0
    Return @@Error
  Close CursorCross
  Deallocate CursorCross
  Return 0
End

go


  江蘇 廣西 北京 天津 浙江 西藏 雲南 遼寧 香港 甘肅 山西 山東
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章