使用 APPLY 運算符可以為實現查詢操作的外部表表達式返回的每個行調用表值函數。表值函數作為右輸入,外部表表達式作為左輸入。通過對右輸入求值來獲得左輸入每一行的計算結果,生成的行被組合起來作為最終輸出。APPLY 運算符生成的列的列表是左輸入中的列集,后跟右輸入返回的列的列表。
注意:若要使用 APPLY,數據庫兼容級別必須至少為 90。
APPLY 有兩種形式:CROSS APPLY 和 OUTER APPLY。CROSS APPLY 僅返回外部表中通過表值函數生成結果集的行。OUTER APPLY 既返回生成結果集的行,也返回不生成結果集的行,其中表值函數生成的列中的值為 NULL。
好久沒寫SQL了,手都有點生了。哈哈,今天回答個問題。順便記錄下來。
事主的需求
事主的問題應該是想把最新的數據和次新數據放在一行里顯示。
因為沒有說明重復的情況如何處理,即有多個最新數據或者有多個次新數據,所以我沒有做過多的處理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
--by wls -- --網絡代碼有風險 --復制粘貼須謹慎 USE tempdb GO IF OBJECT_ID( 't_TestbyWLS' , 'U' ) IS NOT NULL DROP TABLE t_TestbyWLS GO CREATE TABLE t_TestbyWLS(PName NVARCHAR(),PSId INTEGER ,ChkDate NVARCHAR(),Price FLOAT ) GO INSERT INTO t_TestbyWLS VALUES ( 'A' ,, '' ,.) ,( 'B' ,, '' ,.) --,('B',,'',.) ,( 'A' ,, '' ,.) ,( 'B' ,, '' ,.) ,( 'A' ,, '' ,.) --,('A',,'',.) GO SELECT * FROM t_TestbyWLS GO /* SELECT PName,PSId,ChkDate,Price,DENSE_RANK() OVER(PARTITION BY PName ORDER BY CAST (Chkdate AS INTEGER ) DESC ) AS DRID, ROW_NUMBER() OVER(PARTITION BY PName ORDER BY CAST (Chkdate AS INTEGER ) DESC ,Price DESC ) AS RID FROM t_TestbyWLS GO */ WITH TempChkDate AS ( SELECT PName,PSId,ChkDate,Price,DENSE_RANK() OVER(PARTITION BY PName ORDER BY CAST (Chkdate AS INTEGER ) DESC ) AS DRID, ROW_NUMBER() OVER(PARTITION BY PName ORDER BY CAST (Chkdate AS INTEGER ) DESC ,Price DESC ) AS RID FROM t_TestbyWLS ) SELECT tcd.PName,tcd.PSID,tcd.ChkDate,tcd.Price,/*tcd.DRID,tcd.RID,*/t.tcd,t.tp FROM TempChkDate AS tcd CROSS APPLY( SELECT ChkDate AS tcd, Price AS tp FROM TempChkDate WHERE --tcd.DRID= AND tcd.PName=TempChkDate.PName AND tcd.PSId=TempChkDate.PSId AND TempChkDate.Drid= ) AS t WHERE tcd.DRID= GO |
運行的結果應該是正確的。
但是看執行計劃,不是很好啊。
有空再改改。
你可以嘗試一下這個,看看是什么結果。
產生這種原因是因為你沒有做出具體規定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
--by wls -- --網絡代碼有風險 --復制粘貼須謹慎 ------------------------------------------------------------------------ --你可以嘗試一下這個,看看是什么結果。 --產生這種原因是因為沒有做出具體規定。 ------------------------------------------------------------------------ USE tempdb GO IF OBJECT_ID( 't_TestbyWLS' , 'U' ) IS NOT NULL DROP TABLE t_TestbyWLS GO CREATE TABLE t_TestbyWLS(PName NVARCHAR(),PSId INTEGER ,ChkDate NVARCHAR(),Price FLOAT ) GO INSERT INTO t_TestbyWLS VALUES ( 'A' ,, '' ,.) ,( 'B' ,, '' ,.) ,( 'B' ,, '' ,.) ,( 'A' ,, '' ,.) ,( 'B' ,, '' ,.) ,( 'A' ,, '' ,.) ,( 'A' ,, '' ,.) GO WITH TempChkDate AS ( SELECT PName,PSId,ChkDate,Price,DENSE_RANK() OVER(PARTITION BY PName ORDER BY CAST (Chkdate AS INTEGER ) DESC ) AS DRID, ROW_NUMBER() OVER(PARTITION BY PName ORDER BY CAST (Chkdate AS INTEGER ) DESC ,Price DESC ) AS RID FROM t_TestbyWLS ) SELECT tcd.PName,tcd.PSID,tcd.ChkDate,tcd.Price,tcd.DRID,tcd.RID,t.tcd,t.tp FROM TempChkDate AS tcd CROSS APPLY( SELECT ChkDate AS tcd, Price AS tp FROM TempChkDate WHERE --tcd.DRID= AND tcd.PName=TempChkDate.PName AND tcd.PSId=TempChkDate.PSId AND TempChkDate.Drid= ) AS t WHERE tcd.DRID= GO |
以上內容是小編給大家介紹的SQLServer 2008 R2中使用Cross apply統計最新數據和最近數據的相關知識,希望對大家有所幫助!