窗口功能没有按预期工作,为什么?

问题描述 投票:0回答:1

我不明白当你不指定分区时窗框是如何计算的

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` 

顺序已更改...尽管我是按字母排序...那么为什么其他列会影响窗口函数?

我阅读了文档,但到目前为止我找不到任何有关此的信息。这没有任何意义。

google-bigquery
1个回答
0
投票

这里重要的是您要通过窗口函数中的

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 会执行最简单的操作 - 但对查询的微小更改(例如选择其他列)会影响结果)。

    

© www.soinside.com 2019 - 2024. All rights reserved.