我正在尋找當前 最后 X N 行的總和。我可以使用以下查詢來做到這一點,但是它的可擴展性不是很好。
SELECT [id], [amount] LAG([amount],6) OVER(ORDER BY [id]) LAG([amount],12) OVER(ORDER BY [id]) LAG([amount],18) OVER(ORDER BY [id])
如果在此示例中,我將找到“金額”的當前值,再加上最后 3 個“金額”,將 6 分開:
- X = 3
- N = 6
我將在動態查詢中使用這些,并且不希望每次都構建如此復雜的查詢。在某些查詢中可能存在許多“滯后”。有沒有另一種方法來撰寫這個更具可擴展性的查詢?
源資料
| ID | 數量 |
|---|---|
| 1 | 107.35 |
| 2 | 105.41 |
| 3 | 104.63 |
| 4 | 106.7 |
| 5 | 108.7 |
| 6 | 110.21 |
| 7 | 108.8 |
| 8 | 108.91 |
| 9 | 108.5 |
| 10 | 106.66 |
| 11 | 105.2 |
| 12 | 106.5 |
| 13 | 108.27 |
| 14 | 109.72 |
| 15 | 111.53 |
| 16 | 112.8 |
| 17 | 109.03 |
| 18 | 115.31 |
| 19 | 115.56 |
| 20 | 116.85 |
| 21 | 116.08 |
| 22 | 117.61 |
| 23 | 118.31 |
| 24 | 119.25 |
| 25 | 118.45 |
| 26 | 118.43 |
| 27 | 120.16 |
| 28 | 122.5 |
| 29 | 125.57 |
| 30 | 125.65 |
預期成績
| ID | 最后 4 項的總和 |
|---|---|
| 1 | 空值 |
| 2 | 空值 |
| 3 | 空值 |
| 4 | 空值 |
| 5 | 空值 |
| 6 | 空值 |
| 7 | 空值 |
| 8 | 空值 |
| 9 | 空值 |
| 10 | 空值 |
| 11 | 空值 |
| 12 | 空值 |
| 13 | 空值 |
| 14 | 空值 |
| 15 | 空值 |
| 16 | 空值 |
| 17 | 空值 |
| 18 | 空值 |
| 19 | 439.98 |
| 20 | 440.89 |
| 21 | 440.74 |
| 22 | 443.77 |
| 23 | 441.24 |
| 24 | 451.27 |
| 25 | 451.08 |
| 26 | 453.91 |
| 27 | 456.27 |
| 28 | 459.57 |
| 29 | 458.11 |
| 30 | 466.71 |
uj5u.com熱心網友回復:
最好的猜測是,您想要的似乎是這樣的:
DECLARE @X int = 3,
@N int = 6;
SELECT YT.ID,
YT.Amount,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY G.Grp ORDER BY ID) < @X 1 THEN NULL
ELSE SUM(Amount) OVER (PARTITION BY G.Grp ORDER BY ID
ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
END
FROM dbo.YourTable YT
CROSS APPLY (VALUES(ID % @N))G(Grp)
ORDER BY YT.ID;
但是,您會注意到,3在一個地方是硬編碼的,因為您不能在ROWS BETWEEN子句中使用變數。如果您需要對此進行引數化,則需要使用動態 SQL:
DECLARE @X int = 3,
@N int = 6;
DECLARE @SQL nvarchar(MAX),
@CRLF nchar(2) = NCHAR(13) NCHAR(10);
SET @SQL = CONCAT(N'SELECT YT.ID,', @CRLF,
N' YT.Amount,', @CRLF,
N' CASE WHEN ROW_NUMBER() OVER (PARTITION BY G.Grp ORDER BY ID) < @X 1 THEN NULL', @CRLF,
N' ELSE SUM(Amount) OVER (PARTITION BY G.Grp ORDER BY ID', @CRLF,
N' ROWS BETWEEN ',@X,N' PRECEDING AND CURRENT ROW)', @CRLF, --I don't like injecting raw values, but if @X is an int, it is "safe"
N' END', @CRLF,
N'FROM dbo.YourTable YT', @CRLF,
N' CROSS APPLY (VALUES(ID % @N))G(Grp)', @CRLF,
N'ORDER BY YT.ID;');
PRINT @SQL; --Your best debugging friend
EXEC sys.sp_executesql @SQL, N'@X int, @N int', @X, @N;
db<>小提琴
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/467838.html
上一篇:將兩個字串轉換并合并為表格
