日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java动态交叉表,SqlServer如何生成动态交叉表查询

發布時間:2023/12/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java动态交叉表,SqlServer如何生成动态交叉表查询 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為了說明問題,我們用SqlServer自帶的事例數據庫(Northwind)來進行驗證,所有的例子請放到Northwind中運行,我可能會省略Use語句,所引用的表,都是Northwind中的,下面我就不再說明了

這里指的交叉表,就是象Access的交叉表查詢一樣的效果,比如Employees表中City字段代表了城市的名稱,TitleOfCourtesy代表稱呼,我們希望按照City和TitleOfCourtesy的情況來統計ReportsTo字段的合計數(本統計沒有任何實際意義,只是挑選一些記錄包含重復內容的字段來說明情況),并顯示成以下格式:(TitleOfCourtesy作為行,City作為列)

探討這個問題之前,我們首先來看一下如何建立靜態的交叉表,也就是說列數固定的交叉表,這種情況其實只要一句簡單的Select查詢就可以搞定:

SELECT

TitleOfCourtesy,

SUM

(

CASE

City

WHEN

'

London

'

THEN

ReportsTo

ELSE

NULL

END

)

AS

[

London?City

]

,

SUM

(

CASE

City

WHEN

'

Redmond

'

THEN

ReportsTo

ELSE

NULL

END

)

AS

[

Redmond?City

]

,

SUM

(

CASE

City

WHEN

'

Seattle

'

THEN

ReportsTo

ELSE

NULL

END

)

AS

[

Seattle?City

]

FROM

Employees

GROUP

BY

TitleOfCourtesy

其中利用了CASE語句判斷,如果是相應的列,則取需要統計的ReportsTo數值,否則取NULL,然后再合計

其中有兩個常見問題說明一下:

a、用NULL而不用0是有道理的,假如用0,雖然求和函數SUM可以取到正確的數,但類似COUNT函數(取記錄個數),結果就不對了,因為Null不算一條記錄,而0要算,同理空字串("")也是這樣,總之在這里應該用NULL,這樣任何函數都沒問題。

b、假如在視圖的設計界面保存以上的查詢,則會報錯“沒有輸出列”,從而無法保存,其實只要在查詢前面加上一段:Create View ViewName AS ...,ViewName是你準備給查詢起的名稱,...就是我們的查詢,然后運行一下,就可以生成視圖了,對于其他一些設計器不支持的語法,也可以這樣保存。

以上查詢作用也很大,對于很多情況,比如按照季度統計、按照月份統計等列頭內容固定的情況,這樣就行了,但往往大多數情況下列頭內容是不固定的,象City,用戶隨時可能刪除、添加一些城市,這種情況,我們就需要用存儲過程來解決:

總體思路其實很簡單,首先檢索列頭信息,形成一個游標,然后遍歷游標,將上面查詢語句里Case判斷的內容用游標里的值替代,形成一條新的Sql查詢,然后執行,返回結果,就可以了,以下是我寫的一個存儲過程,供大家參考:

CREATE

procedure

CorssTab

@strTabName

as

varchar

(

50

)

=

'

Employees

'

,

--

此處放表名

@strCol

as

varchar

(

50

)

=

'

City

'

,

--

表頭分組依據字段

@strGroup

as

varchar

(

50

)

=

'

TitleOfCourtesy

'

,

--

分組字段

@strNumber

as

varchar

(

50

)

=

'

ReportsTo

'

,

--

被統計的字段

@strSum

as

varchar

(

10

)

=

'

Sum

'

--

運算方式

AS

DECLARE

@strSql

as

varchar

(

1000

),

@strTmpCol

as

varchar

(

100

)

EXECUTE

(

'

DECLARE?corss_cursor?CURSOR?FOR?SELECT?DISTINCT

'

+

@strCol

+

'

from

'

+

@strTabName

+

'

for?read?only

'

)

--

生成游標

begin

SET

nocount

ON

SET

@strsql

=

'

select

'

+

@strGroup

+

'

,

'

+

@strSum

+

'

(

'

+

@strNumber

+

'

)?AS?[

'

+

@strSum

+

'

of

'

+

@strNumber

+

'

]

'

--

查詢的前半段

OPEN

corss_cursor

while

(

0

=

0

)

BEGIN

FETCH

NEXT

FROM

corss_cursor

--

遍歷游標,將列頭信息放入變量@strTmpCol

INTO

@strTmpCol

if

(

@@fetch_status

<>

0

)

break

SET

@strsql

=

@strsql

+

'

,

'

+

@strSum

+

'

(CASE

'

+

@strCol

+

'

WHEN

'''

+

@strTmpCol

+

'''

THEN

'

+

@strNumber

+

'

ELSE?Null?END)?AS?[

'

+

@strTmpCol

+

'

'

+

@strCol

+

'

]

'

--

構造查詢

END

SET

@strsql

=

@strsql

+

'

from

'

+

@strTabname

+

'

group?by

'

+

@strGroup

--

查詢結尾

EXECUTE

(

@strsql

)

--

執行

IF

@@error

<>

0

RETURN

@@error

--

如果出錯,返回錯誤代碼

CLOSE

corss_cursor

DEALLOCATE

corss_cursor

RETURN

0

--

釋放游標,返回0表示成功

end

GO

幾點說明:

a、這是一個通用存儲過程,使用時@strTabName、@strCol、@strGroup、@strNumber、@strSum幾個變量設置一下就可以用到其他表上,其中結果集的第二列我加了個合計列

b、為了測試方便,我在存儲過程中設置了默認值,就是前面提到的Employees表,這樣直接運行時就可以出來我上面提到的結果。

c、使用時,可以把上面的代碼復制到企業管理器的查詢設計界面Sql窗格,或者查詢分析器里運行一下(注意正確選擇NorthWind數據庫),就可以生成一個存儲過程:CorssTab,然后直接運行CorssTab,如果出現本文前面類似的窗格,就表示運行成功了。

d、假如用于其它表,首先需要在你的用戶數據庫里生成此存儲過程(當然也可以放到Master里,然后再加個變量:@DataBase,賦值為數據庫名稱,然后在上面代碼打開指定數據庫,這樣所有的數據庫都可以調用它),當你調用時,采取以下格式:

CorssTab @strTabName = 'Orders', @strCol = 'DATEPART(yy, OrderDate)',@strGroup = 'CustomerID', @strNumber = 'OrderID', @strSum = 'Count'

上面這條語句統計了NorthWind中Orders表里每個客戶年度訂單數量,大家可以運行試一下效果,雖然列頭顯示的名稱不恰當,但基本效果出來了,相信大家通過對我的代碼再作簡單修改,可以達到滿意的交叉表效果。

總結

以上是生活随笔為你收集整理的java动态交叉表,SqlServer如何生成动态交叉表查询的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。