【发布时间】:2012-06-22 09:54:39
【问题描述】:
我正在使用 PostgreSQL,我想减去同一张表的两条记录并在同一个查询中使用结果。
这是表格:
分数
6
8
9
结果
6
2
1
我想做什么:
Result = Score(i) - Score(i-1)
最后我想要这些结果的总和。在我的示例中,sum(result) 必须是 9。
【问题讨论】:
标签: sql postgresql window-functions
我正在使用 PostgreSQL,我想减去同一张表的两条记录并在同一个查询中使用结果。
这是表格:
6
8
9
6
2
1
我想做什么:
Result = Score(i) - Score(i-1)
最后我想要这些结果的总和。在我的示例中,sum(result) 必须是 9。
【问题讨论】:
标签: sql postgresql window-functions
您需要一些方法来确定score 中的行顺序。关系数据库中的表中没有“自然顺序”。所以我假设你有一个id(或时间戳或其他东西)来订购你的记录。还是i 保证在每一行中都更大?然后你可以通过i订购。
查询本身很简单——一旦你发现window functions:
SELECT i - lag(i, 1, 0) OVER (ORDER BY id) AS result
FROM score
ORDER BY id;
包括@Clodoaldo 的改进(见评论)。
lag(i, 1, 0) OVER (ORDER BY id)
等价于,但比:
COALESCE(lag(i) OVER (ORDER BY id), 0)
目的是覆盖第一行没有前行的特殊情况。
Demo on sqlfiddle.
sum(result) 是微不足道的,因为根据您的描述,它必然等于最后一个 i:
SELECT i
FROM score
ORDER BY id DESC
LIMIT 1;
【讨论】:
lag(i, 1, 0) 代替coalesce 不是更好吗?
类似
SELECT SUM(COALESCE(rx.diff,rx.val))
FROM
(SELECT x.val,
x.val - lag(x.val) over () as diff
FROM (SELECT unnest(ARRAY[6,8,9]) as val) AS x) AS rx
用你的表选择代替我的 unnest,它只是根据你的例子生成数据。
【讨论】:
ORDER BY 子句。没有它,lag() 的结果是(特定于实现的)任意的。另外,COALESCE 放错地方了。