程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> SQL實現動態交叉表

SQL實現動態交叉表

編輯:關於SqlServer

動態交叉表就是列表可以根據表中數據的情況動態創建列。

動態查詢不能使用Select語句實現,它可以利用存儲過程實現。思路是:

首先檢索列頭信息,形成一個游標,然後遍歷游標,將上面靜態交叉表實現過程中使用Case語句判斷的內容用游標裡的值替代,形成一條新的Sql查詢語句,然後執行並返回結果。下面是一個通用的實現動態交叉表的存儲過程:

CREATE procedure proc_across_table
@TableName as varchar(50), --生成交叉表依據的表名
@NewColumn as varchar(50), --生成表頭依據的字段名
@GroupColumn as varchar(50), --分組依據的字段名
@StatColumn as varchar(50), --欲統計的字段名
@Operator as varchar(10) --統計的運算方式
AS
DECLARE @SQL as varchar(1000), @Column as varchar(50) --定義參數
EXECUTE ('DECLARE cursor_new_column CURSOR FOR SELECT DISTINCT ' + @NewColumn + ' from ' + @TableName + ' for read only ') --定義游標
begin
SET nocount ON
SET @SQL='select ' + @GroupColumn + ', ' + @Operator + '(' + @StatColumn + ') AS [' + @Operator + ' of ' + @StatColumn + ']' --定義SQL語句頭
OPEN cursor_new_column
while (0=0)
BEGIN --遍歷游標
FETCH NEXT FROM cursor_new_column INTO @Column --通過游標獲取列頭信息
if (@@fetch_status<>0) break
SET @SQL = @SQL + ', ' + @Operator + '(CASE ' + @NewColumn + ' WHEN ''' + @Column + ''' THEN ' + @StatColumn + ' ELSE Null END) AS [' + @Column + ']' --循環追加SQL語句
END
SET @SQL = @SQL + ' from ' + @TableName + ' group by ' + @GroupColumn --定義SQL語句尾
EXECUTE(@SQL) --執行SQL語句
PRINT @SQL --輸出SQL語句
IF @@error <>0 RETURN @@error --如果出錯,則返回錯誤代碼
CLOSE cursor_new_column --關閉游標
DEALLOCATE cursor_new_column RETURN 0 --釋放游標,釋放成功則返回0
end
GO

在SQL Server查詢分析器上執行下面的代碼,就可以得到動態交叉表。

proc_across_table '商品銷售表', '訂單號', '商品名', '訂貨數量', 'SUM'

 

在SQL Server查詢分析器上調用存儲過程時,最前面的為將要調用的存儲過程的名稱,後面為執行存儲過程需要的參數,參數用引號括起,存儲過程名稱與參數之間用空格分隔,參數之間用逗號分隔。

說明:這是一個通用的存儲過程,只要正確的傳入生成交叉表依據的表名(@TableName)、生成表頭依據的字段名(@NewColumn)、生成主鍵列依據的字段名(@GroupColumn)、欲統計的字段名(@StatColumn)和統計的運算方式(@Operator),就可以成功的將其應用到任何數據表中。

實現動態交叉表時用到了游標,下面對游標進行詳細介紹。

每個游標有4個組成部分,這4個組成部分必須符合下面的順序:

(1)聲明游標;

(2)打開游標;

(3)從一個游標中查找信息;

(4)關閉游標。

其中,聲明游標主要使用DECLARE CURSOR語句,下面介紹該語句。

語法:

DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]

cursor_name:用於指定游標的名稱。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved