COUNT(*) OVER(ORDER BY...)窗口函数结果存疑,求原理解析
窗口函数COUNT(*) OVER(ORDER BY ...)的工作原理
你遇到的问题核心是对窗口函数框架范围的误解,以下拆解具体逻辑:
- 当窗口函数的OVER子句仅包含
ORDER BY而无PARTITION BY时,确实会把所有200条记录视为一个单独分区,但窗口的计算范围不是整个分区,而是从分区起始行到与当前行ORDER BY列值相同的所有行(默认框架是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)。 COUNT(*) OVER(ORDER BY registration_time desc)的计算逻辑是:对每一行,统计当前窗口内(从第一行到所有和当前行注册时间相同的行)的总行数。比如你提到的两行注册时间为'2018-01-01'的记录,当计算这两行时,窗口包含了前3条更早的记录加上这两行,总共5条,所以它们的cnt都显示为5。- 你预期的每行cnt为1是错误的理解:COUNT(*)在窗口中是统计窗口内的行数,而非每行单独计数。如果想要每行显示1,直接写
1 as cnt即可;如果想要统计整个表的总行数(每行都显示200),需要去掉ORDER BY,写成COUNT(*) OVER() as cnt。 - 你觉得结果类似
SUM(1) OVER(ORDER BY ... rows unbounded preceding),其实两者有细微区别:ROWS UNBOUNDED PRECEDING是按物理行范围计算(到当前行为止的所有物理行),而默认的RANGE是按ORDER BY列的逻辑值范围计算(所有和当前行ORDER BY值相同的行都会被纳入同一窗口),这也是为什么相同注册时间的行cnt值相同的原因。
内容的提问来源于stack exchange,提问作者MordecaiOD
相关产品推荐
相关产品推荐

