CTE的救援(再次):
DROP TABLE tmp.sums;
CREATE TABLE tmp.sums
(id INTEGER NOT NULL
, zdate timestamp not null
, amount integer NOT NULL
);
INSERT INTO tmp.sums (id,zdate,amount) VALUES
(1, '2011-10-24', 1),(1, '2011-10-25', 2),(1, '2011-10-26', 3)
,(2, '2011-10-24', 11),(2, '2011-10-25', 12),(2, '2011-10-26', 13)
;
WITH RECURSIVE list AS (
-- Terminal part
SELECT t0.id, t0.zdate
, t0.amount AS amount
, t0.amount AS runsum
FROM tmp.sums t0
WHERE NOT EXISTS (
SELECT * FROM tmp.sums px
WHERE px.id = t0.id
AND px.zdate < t0.zdate
)
UNION
-- Recursive part
SELECT p1.id AS id
, p1.zdate AS zdate
, p1.amount AS amount
, p0.runsum + p1.amount AS runsum
FROM tmp.sums AS p1
, list AS p0
WHERE p1.id = p0.id
AND p0.zdate < p1.zdate
AND NOT EXISTS (
SELECT * FROM tmp.sums px
WHERE px.id = p1.id
AND px.zdate < p1.zdate
AND px.zdate > p0.zdate
)
)
SELECT * FROM list
ORDER BY id, zdate;
輸出:
DROP TABLE
CREATE TABLE
INSERT 0 6
id | zdate | amount | runsum
----+---------------------+--------+--------
1 | 2011-10-24 00:00:00 | 1 | 1
1 | 2011-10-25 00:00:00 | 2 | 3
1 | 2011-10-26 00:00:00 | 3 | 6
2 | 2011-10-24 00:00:00 | 11 | 11
2 | 2011-10-25 00:00:00 | 12 | 23
2 | 2011-10-26 00:00:00 | 13 | 36
(6 rows)
有很多答案在SO運行SQL總的問題。查看http://stackoverflow.com/questions/7357516/subquery-or-leftjoin-with-group-by-which-one-is-faster瞭解更多詳情。或者本文檔http://www.insidetsql.com/OVER_Clause_and_Ordered_Calculations.doc – MatBailie
注意:上面引用的問題和文檔顯示,對於幾乎任何數據大小,遊標都快於半笛卡爾積。我強烈建議避免這種解決方案。 – MatBailie