SQL中ORDER BY子句搭配窗口函数的行为及结果解析
窗口函数在ORDER BY中的工作原理及案例分析
一、窗口函数在ORDER BY中的通用工作原理
窗口函数在ORDER BY子句中执行时,会先为查询结果的每一行独立计算窗口函数的输出值,之后ORDER BY子句就以这个计算值作为排序依据,对所有行进行排序。
窗口函数的核心是为每行定义一个"窗口"(即与当前行关联的一组行),再对这组行执行计算。当窗口函数的OVER子句中包含ORDER BY时,默认的窗口范围是从排序后的第一行到当前行(等价于RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),这类窗口常用来计算累加、累计排名等。
二、你的案例具体拆解
先看你的transactions表数据:
| id | date | amount | +----+------------+--------+ | 1 | 2023-01-01 | 3 | | 2 | 2023-02-01 | 5 | | 3 | 2023-03-01 | 4 | | 4 | 2023-04-01 | 2 | | 5 | 2023-05-01 | 7 | | 6 | 2023-06-01 | 4 | +----+------------+--------+
你的查询是:
SELECT * FROM transactions ORDER BY SUM(amount) OVER (ORDER BY id) < 15;
1. 计算每行的窗口函数结果
SUM(amount) OVER (ORDER BY id)会按id升序,计算从第一行到当前行的累加和,再判断这个累加和是否小于15,得到布尔值:
| id | 累加和(按id排序) | SUM(amount) <15 |
|---|---|---|
| 1 | 3 | TRUE |
| 2 | 3+5=8 | TRUE |
| 3 | 8+4=12 | TRUE |
| 4 | 12+2=14 | TRUE |
| 5 | 14+7=21 | FALSE |
| 6 | 21+4=25 | FALSE |
2. 排序逻辑解析
SQL中布尔值排序时会被转换为数值:FALSE对应0,TRUE对应1。ORDER BY默认是升序排序,所以数值更小的0(即SUM(amount) <15为FALSE的行)会排在前面,数值更大的1(即结果为TRUE的行)排在后面。
这就是为什么查询结果里id=5、6的行先出现,之后是id=1-4的行。另外,同一排序分组内(比如都是FALSE的行),如果没有指定额外排序条件,数据库返回的顺序是未定义的(这里id5在6前面只是常见的存储顺序表现,SQL标准不保证)。
内容的提问来源于stack exchange,提问作者Bilal
相关产品推荐
相关产品推荐

