「这是我参与11月更文挑战的第 20 天,活动详情查看:2021最后一次更文挑战」
如果没有指定ORDER BY子句,那么窗口分区中的所有行都被认为是当前行的对等行,下面的查询说明了这一点:
SELECT
number,
sum(number) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
FROM numbers(1, 3)
/* answer */
┌─number─┬─sum(number) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW)─┐
│ 1 │ 6 │
│ 2 │ 6 │
│ 3 │ 6 │
└────────┴──────────────────────────────────────────────────────────────┘
我们可以看到的是,现在窗口函数对每一行都返回相同的结果。为什么呢?
很简单:我们没有任何ORDER BY子句,结果中的所有行都被认为是当前行的同行。虽然frame仍然在窗口内滑动,每条当前行的frame总是包含所有的行。
一般来说,一个窗口既可以包括结果集中的所有行,也可以使用 PARTITION BY
子句将结果集划分为独立的窗口。所以,当没有指定PARTITION BY子句时,所有的行都会落入一个大的分区,也被称为窗口。每个窗口中的行可以使用ORDER BY子句进行排序。
当你试图理解这个功能时,窗口的比喻就很方便了。就像下面的概念图所示,在心中创建一个窗口的模拟图像,让你看到结果集中的所有行,或者只是其中的一些块。
不过上述的表达有几个需要单独拿出来说一下(不然确实有点蒙):
- 停下来看看
frame
到底代表什么?在前面我们使用过:ROWS以及RANGE
从英文表达上来看,说白了:
- ROWS:针对的是行间隔,也就是frame中跨越的行数
- RANGE:针对的是行所对应的值,
RANGE 1 PRECEDING
是和当前行的值相差1形成一个frame
- 而在前面
Peers
:
可以理解为:和 current ROW 分在一个桶(也可以理解为分组)。只适用于 Range frame