在 Informix 中考虑以下语句:
SELECT
a,
b,
sum(a) over (order by b) "no frame",
sum(a) over (order by b range between unbounded preceding and current row) "range",
sum(a) over (order by b rows between unbounded preceding and current row) "rows"
FROM TABLE(SET{row(1, 1), row(2, 1), row(3, 2), row(4, 2)}) AS t(a, b);
令人惊讶的是,它为range
和rows
产生了相同的结果:
a |b |no frame |range |rows |
--|--|---------|------|-----|
1 |1 |3 |1 |1 |
2 |1 |3 |3 |3 |
3 |2 |10 |6 |6 |
4 |2 |10 |10 |10 |
这与我习惯使用的任何RDBMS(包括 PostgreSQL )完全不同:
SELECT
a,
b,
sum(a) over (order by b) "no frame",
sum(a) over (order by b range between unbounded preceding and current row) "range",
sum(a) over (order by b rows between unbounded preceding and current row) "rows"
FROM (values(1, 1), (2, 1), (3, 2), (4, 2)) AS t(a, b);
...产生预期的结果
a |b |no frame |range |rows |
--|--|---------|------|-----|
1 |1 |3 |3 |1 |
2 |1 |3 |3 |3 |
3 |2 |10 |10 |6 |
4 |2 |10 |10 |10 |
我遗漏的Informix和标准SQL之间是否存在细微差别,还是一个bug?我正在使用official docker image,它与到目前为止的Informix 12.10对应。
答案 0 :(得分:1)
这是documented的行为:
如果为窗口聚合函数指定了ORDER子句但未指定任何窗口框架子句,则默认情况下,将返回当前行和当前行之前的所有行,这等效于以下窗口框架规范:>
未绑定的行和当前行之间的行
我相信当没有窗口条款存在时,标准是RANGE
。我很确定这是大多数其他数据库中的默认设置。
答案 1 :(得分:1)
作为一种解决方法,我可以使用0 PRECEDING
(不应允许,但是很好)代替CURRENT ROW
。这样会产生我期望的结果:
SELECT
a,
b,
sum(a) over (order by b) "no frame",
sum(a) over (order by b range between unbounded preceding and 0 preceding) "range",
sum(a) over (order by b rows between unbounded preceding and current row) "rows"
FROM (values(1, 1), (2, 1), (3, 2), (4, 2)) AS t(a, b);
我现在得到:
a |b |no frame |range |rows |
--|--|---------|------|-----|
1 |1 |3 |3 |1 |
2 |1 |3 |3 |3 |
3 |2 |10 |10 |6 |
4 |2 |10 |10 |10 |