You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

窗口函数中ORDER BY是否新增帧?不同写法的计算逻辑问询

窗口函数SUM() OVER()的分组与排序逻辑解析

一、基础分组求和(无ORDER BY)

使用语句:

sum(Age) over(partition by Country) as Total

执行结果:

Id          FirstName       LastName   Age         Country         Total      
----------- --------------- ---------- ----------- --------------- -----------
          5 Betty           Doe                 28 UAE                      28
          6 Fred            XXX                  1 UK                    99731
          7 Angela          XXX                 37 UK                    99731
          8 Dave            XXX               2000 UK                    99731
          9 Tony            YYY               9000 UK                    99731
         10 Tony            ZZZ                323 UK                    99731
         11 Pete            ZZZ              88323 UK                    99731
          3 David           Robinson            22 UK                    99731
          4 John            Reinhardt           25 UK                    99731
          1 John            Doe                 31 USA                      53
          2 Robert          Luna                22 USA                      53

这个逻辑很清晰:按Country将数据分成3个独立分区(UAE、UK、USA),每个分区内计算所有行的Age总和,因此同一分区的所有行Total值完全一致。

二、分组加排序的窗口求和(partition by + order by)

使用语句:

sum(Age) over(partition by Country order by LastName) as Total

执行结果:

Id          FirstName       LastName   Age         Country         Total      
----------- --------------- ---------- ----------- --------------- -----------
          5 Betty           Doe                 28 UAE                      28
          4 John            Reinhardt           25 UK                       25
          3 David           Robinson            22 UK                       47
          6 Fred            XXX                  1 UK                     2085
          7 Angela          XXX                 37 UK                     2085
          8 Dave            XXX               2000 UK                     2085
          9 Tony            YYY               9000 UK                    11085
         10 Tony            ZZZ                323 UK                    99731
         11 Pete            ZZZ              88323 UK                    99731
          1 John            Doe                 31 USA                      31
          2 Robert          Luna                22 USA                      53

这里的核心规则是:当窗口函数的OVER()子句中加入ORDER BY时,默认启用「累积求和」的窗口帧规则——窗口范围是「分区起始行到当前行(及所有与当前行排序键值相同的行)」。

以UK分区为例,按LastName排序后顺序为:Reinhardt → Robinson → XXX → YYY → ZZZ:

  • 第一行(Reinhardt):窗口仅包含自身,Total=25
  • 第二行(Robinson):窗口包含Reinhardt + Robinson,Total=25+22=47
  • 第三到第五行(XXX):这三行LastName相同,窗口包含前面所有行(Reinhardt+Robinson+所有XXX行),Total=25+22+1+37+2000=2085
  • 第六行(YYY):窗口包含前面所有行到YYY,Total=2085+9000=11085
  • 第七到第八行(ZZZ):窗口包含所有UK行,Total=11085+323+88323=99731

这看起来类似按Country, LastName分组后累加,但本质是排序后的累积求和,相同排序键的行会共享同一个累积值。

三、多列分组加排序的窗口求和

使用语句:

sum(Age) over(partition by Country, LastName order by FirstName) as Total

执行结果:

Id          FirstName       LastName   Age         Country         Total      
----------- --------------- ---------- ----------- --------------- -----------
          5 Betty           Doe                 28 UAE                      28
          4 John            Reinhardt           25 UK                       25
          3 David           Robinson            22 UK                       22
          7 Angela          XXX                 37 UK                       37
          8 Dave            XXX               2000 UK                     2037
          6 Fred            XXX                  1 UK                     2038
          9 Tony            YYY               9000 UK                     9000
         11 Pete            ZZZ              88323 UK                    88323
         10 Tony            ZZZ                323 UK                    88646
          1 John            Doe                 31 USA                      31
          2 Robert          Luna                22 USA                      22

这个语句的逻辑拆解:

  1. 先按Country + LastName组合分区,比如UK的XXX是一个独立分区,UK的ZZZ是另一个独立分区
  2. 每个分区内按FirstName排序
  3. 同样遵循累积求和的窗口帧规则:窗口范围是「当前分区的起始行到当前行」

拿UK的XXX分区举例,按FirstName排序后顺序是Angela → Dave → Fred:

  • 第一行(Angela):窗口仅包含自身,Total=37
  • 第二行(Dave):窗口包含Angela+Dave,Total=37+2000=2037
  • 第三行(Fred):窗口包含Angela+Dave+Fred,Total=2037+1=2038

而UK的ZZZ分区,按FirstName排序后是Pete → Tony:

  • 第一行(Pete):Total=88323
  • 第二行(Tony):Total=88323+323=88646

和第二个语句的区别在于:第二个语句的分区是Country,排序后累积整个分区内的行;而这个语句的分区是Country+LastName,每个小分区内独立排序累积,因此不会跨LastName求和。


测试代码

-- create
CREATE TABLE Customer (
  Id int,
  FirstName varchar(15),
  LastName varchar(10),
  Age int,
  Country varchar(15)
);

-- insert
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (1, 'John', 'Doe', 31, 'USA');
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (2, 'Robert', 'Luna', 22, 'USA');
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (3, 'David', 'Robinson', 22, 'UK');
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (4, 'John', 'Reinhardt', 25, 'UK');
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (5, 'Betty', 'Doe', 28, 'UAE');
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (6, 'Fred', 'XXX', 1, 'UK');
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (7, 'Angela', 'XXX', 37, 'UK');
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (8, 'Dave', 'XXX', 2000, 'UK');
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (9, 'Tony', 'YYY', 9000, 'UK');
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (10, 'Tony', 'ZZZ', 323, 'UK');
INSERT INTO Customer(Id,FirstName,LastName,Age,Country) VALUES (11, 'Pete', 'ZZZ', 88323, 'UK');


SELECT 
    Id,
    FirstName,
    LastName,
    Age,
    Country,
    sum(Age) over(partition by Country) as Total
    --sum(Age) over(partition by Country order by LastName) as Total
    --sum(Age) over(partition by Country, LastName order by FirstName) as Total
FROM Customer

内容的提问来源于stack exchange,提问作者jessejbweld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:19:49