我想刪除SQL中的遊標,以提高性能(並且因爲我想學習如何使用最佳實踐,並且最佳實踐應該基於,無需光標進行設置)。刪除cursur SQL語句
無論如何,我有一個臨時表看起來像這樣:
+------------+--------+-------+----+
| Period | Change | Value | NR |
+------------+--------+-------+----+
| 201705 | 7 | 26055 | 1 |
| 201704 | 29 | 0 | 2 |
| 201703 | -92 | 0 | 3 |
| 201702 | -338 | 0 | 4 |
| 201701 | 81 | 0 | 5 |
| 201612 | 107 | 0 | 6 |
| 201611 | 72 | 0 | 7 |
| 201610 | 54 | 0 | 8 |
| 201609 | 64 | 0 | 9 |
| 201608 | 47 | 0 | 10 |
| 201607 | 23 | 0 | 11 |
| 201606 | 45 | 0 | 12 |
+------------+--------+-------+----+
目前,光標的動作如下:
DECLARE @Value INT
BEGIN
DECLARE c_Value CURSOR FOR
SELECT NR
FROM ##TMP
WHERE Value = 0
----
OPEN c_Value
FETCH NEXT FROM c_Value
INTO @Value
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @Value = Value - Change
FROM ##TMP
WHERE NR = (Select MAX(NR) From ##TMP WHERE Value <> 0)
BEGIN
UPDATE ##TMP
SET Value = @Value
WHERE NR = (Select MAX(NR)+1 From ##TMP WHERE Value <> 0)
END
FETCH NEXT FROM c_Value
INTO @Value
END
CLOSE c_Value
DEALLOCATE c_Value
END
結果:
+------------+--------+-------+----+
| Period | Change | Value | NR |
+------------+--------+-------+----+
| 201705 | 7 | 26055 | 1 |
| 201704 | 29 | 26048 | 2 |
| 201703 | -92 | 26019 | 3 |
| 201702 | -338 | 26111 | 4 |
| 201701 | 81 | 26449 | 5 |
| 201612 | 107 | 26368 | 6 |
| 201611 | 72 | 26261 | 7 |
| 201610 | 54 | 26189 | 8 |
| 201609 | 64 | 26135 | 9 |
| 201608 | 47 | 26071 | 10 |
| 201607 | 23 | 26024 | 11 |
| 201606 | 45 | 26001 | 12 |
+------------+--------+-------+----+
那麼,如何我可以實現這個結果,而不使用遊標?我用CTE嘗試過,但我無法得到這個結果。
這不能由一組操作來解決,但你可以使用相關子查詢,窗口函數或遞歸CTE來解決它。請向我們展示您嘗試過的CTE,我們可以從那裏建立。 – Jayvee
什麼是sql版本? –
你應該看看這篇文章:https://msdn.microsoft.com/en-us/library/ms189461(v=sql.110).aspx – tgr