SQL 窗口函数经常使用, 但是在修改历史代码时会经常忽略掉一些隐蔽的默认行为,
使得代码留下 bug, 比如下面两个结果是一样的吗:
sum(..) over(partition by dimension_1) |
答案是不一样的. 为什么呢? 这就要翻出 window frame
的完整定义.
window frame
的完整定义
over()
语法定义:
window_function_name(expression) |
当我们使用 over(partition by dimension_1)
时, 默认省略了一些东西,
那就是默认的 [frame_definition]
这部分, 也就是下面的ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
.
而当我们同时使用了 order by
之后, [frame_definition]
将会采用下面的 [frame_definition]
:RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
.
首先因为 UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
表示将会计算整个 partition by dimension_1
的数据范围,
然而 UNBOUNDED PRECEDING AND CURRENT ROW
只会计算 partition by dimension_1
排序后第一行到 CURRENT ROW
当前行的数据.
因此, 两者的结果是不同的.
默认的行为往往是产生 bug 的地方, 即使懂得也容易疏忽.
参考
https://stackoverflow.com/questions/47130030/whats-the-default-window-frame-for-window-functions