我不明白当你不指定分区时窗框是如何计算的
SELECT
COUNT(letter) OVER( ORDER BY letter
ROWS BETWEEN 1 PRECEDING AND 2 FOLLOWING
) as letter_count,
n1, letter
FROM `my_dataset.my_table`
所以我的期望是它会查找上一行、当前行和接下来的两行并且它会计数。什么是计数?它会计算当前字母的出现次数吗?无论我在计算什么,当您指定之间的行时,我都无法弄清楚窗口函数如何运行
这是输出:
letter_count n1 letter
4 2 B
4 4 B
4 1 E
4 4 E
3 3 B
4 5 F
4 2 E
4 4 F
4 0 B
2 7 F
3 2 F
我们取第 1 行(NULL、B、B、E)
总数是3,有2B和1 E......
如果你从整个表中算出所有 B 就有意义了 - 4
但是当你转到第 3 行时,你得到了 (B E E B) 你有 2B 和 2E .. E 在整个表中只有 3 ,但在当前窗口中只有 2 。 如果你数一下这个窗口中的所有字母,你会得到 4 个,这很好......但对于第一个字母来说没有意义,因为你有 3
有趣的是,如果我像这样修改查询:
SELECT letter,
COUNT(letter) OVER( ORDER BY letter
ROWS BETWEEN 1 PRECEDING AND 2 FOLLOWING
) as letter_count,
n1
FROM `my_dataset.my_table`
顺序已更改...尽管我是按字母排序...那么为什么其他列会影响窗口函数?
我阅读了文档,但到目前为止我找不到任何有关此的信息。这没有任何意义。
这里重要的是您要通过窗口函数中的
letter
字段进行排序。
使用窗口函数,您将为源表中的每一行进行计算。要进行此计算,您需要构建一个新表。它将按照您指定的方式订购。
它还可以分区,这意味着对于每个计算,仅考虑某些行。由于您不是分区,因此您构建的表将包含所有行,并按照您指定的方式排序。
这是一张可能的表格,尊重您的
ORDER BY letter
:
n1 letter
2 B
4 B
0 B
3 B
1 E
4 E
2 E
5 F
4 F
7 F
2 F
请注意,您可以通过其他方式对这些行进行排序,同时遵守您的
ORDER BY letter
命令。 BigQuery 将根据数据的实际(物理)存储方式来执行“最简单的操作”。预测 BigQuery 会做什么真的不可能!这就是为什么根据您编写查询的确切方式,您会得到不同的行为。
现在结束:您的窗口现在将逐行移动并仅考虑此有序表的子集。它将抓取前 1 行、“目标”行和后 2 行来进行计算。 计算本身就是
COUNT(letter)
。一般来说,这将返回
4
,除了有序表中的第一行和最后两行。因此,字母为 B
的行中的 one 将具有 3
而不是 4
。其中 F
行将具有 3
,另一行将具有 2
。这正是您所看到的。重要的是,输出行按原始输入顺序放回!
总而言之:您的困惑是由
ORDER BY letter
在窗口子句中的作用性质引起的。当计算完成后,一切都按照这个顺序进行。但是,结果保留原始顺序。
因为ORDER BY letter
顺序不确定(有几种不同的方法),结果有些随机(它们是可重复的 - BigQuery 会执行最简单的操作 - 但对查询的微小更改(例如选择其他列)会影响结果)。