【发布时间】:2014-11-16 20:18:13
【问题描述】:
我有一个简单的表,就是:
DROP TABLE IF EXISTS running_averages;
CREATE TABLE running_averages
(
avg_id SERIAL NOT NULL PRIMARY KEY,
num1 integer,
num2 integer DEFAULT 0
);
INSERT INTO running_averages(num1, num2)
SELECT 100, 100 UNION ALL
SELECT 200, 175 UNION ALL
SELECT -400, NULL UNION ALL
SELECT 300, 200 UNION ALL
SELECT -100, NULL;
在上表中,如果“num1”列为负值,则“num2”列应更新为上一行的累积平均值。我目前的查询是:
SELECT *,
num1 * num2 AS current_total,
SUM(num1 * num2) OVER(order by avg_id) AS cumulative_sum,
SUM(num1) OVER(order by avg_id) AS culmulative_num1,
CASE WHEN num1 > 0 THEN
SUM(num1 * num2) OVER(order by avg_id)
/
SUM(num1) OVER(order by avg_id)
ELSE
0
END AS cumulative_average
FROM running_averages;
结果:
avg_id num1 num2 current_total cumulative_sum cumulative_num1 cumulative_average
1 100 100 10,000 10,000 100 100
2 200 175 35,000 45,000 300 150
3 -400 NULL 45,00 -100 0
4 300 200 60,000 105,000 200 525
5 -100 NULL 105,000 100 0
如果当前行的 num1 列是负数,我无法弄清楚获取上一行的累积平均值的方法。而不是上面的,预期的输出应该是:
avg_id num1 num2 current_total cumulative_sum cumulative_num1 cumulative_average
1 100 100 10,000 10,000 100 100
2 200 175 35,000 45,000 300 150
3 -400 150 -60,000 -15,00 -100 150
4 300 200 60,000 45,000 200 225
5 -100 225 -22,500 22,500 100 225
在这种情况下如何获取最后一行的列的值?
编辑:
我编辑了上面的 SQL 脚本。我很喜欢Gordon Linoff 的回答方法。但遗憾的是,根据脚本更改,它会产生不正确的结果:
avg_id num1 num2 new_num2
1 100 100 100
2 200 175 175
3 -400 150 150 (Correct)
4 300 200 200
5 -100 225 50 (Incorrect)
编辑 2
我也测试了Multisync的答案,它也产生了错误的结果:
avg_id num1 num2 current_total cumulative_sum cumulative_num1 cumulative_average
1 100 100 10,000 10,000 100 100
2 200 175 35,000 45,000 300 150
3 -400 150 (Correct) -60,000 -15,00 -100 150
4 300 200 60,000 45,000 200 225
5 -100 175 (Incorrect) -17,500 27,500 100 275
编辑 3
我已接受 Multisync 的更新答案,因为它会产生正确的结果。我还想知道如何改进这样的查询,因为我们有很多聚合和窗口函数。有关此主题的任何参考资料都会有所帮助。
【问题讨论】:
标签: sql postgresql