开窗函数OVER(PARTITION BY... ORDER BY...)详解

本文深入讲解了Oracle数据库中分析函数OVER(PARTITION BY...ORDER BY...)的使用方法,通过实例展示了如何进行分组排序和求和操作,特别适用于贷款偿还场景下计算剩余本金和利息。

本文转自:【Orcale】分析函数 OVER(PARTITION BY... ORDER BY...)的讲解

项目中用到分组排序,求和之类的,这位小哥写的很详细,记录一下

算当期之后剩余的本金利息和

select rid||'',lid,indexs,should_capital,fact_capital,should_interest,fact_interest,
sum(should_capital) over(partition by lid order by indexs desc) - should_capital as rest_capital,
sum(should_interest) over(partition by lid order by indexs desc) - should_interest as rest_interest
 from ods.s02_loan_repayment; 

<think> 我们被要求解释窗口函数 SUM() OVER (PARTITION BY ...) 的使用方法。根据引用[1][2][3],我们可以知道: 1. 窗口函数的基本结构:function_name(<argument>) OVER (<partition_Clause> <order by_Clause> <windowing_Clause>) 2. SUM() OVER (PARTITION BY ...) 用于对某个字段进行分组求和,同时保持原表的行数(即每行都会返回结果,而不是像GROUP BY那样聚合为一行) 3. 其中,PARTITION BY 用于分组,类似于GROUP BY的分组,但不会合并行;ORDER BY 用于指定组内的排序,如果指定了ORDER BY,则默认的窗口范围是从组内第一行到当前行(即累计求和);ROWS子句可以指定窗口的范围。 我们将按照以下结构回答: 1. 基本语法 2. 核心组成部分(PARTITION BY, ORDER BY, 窗口范围) 3. 使用示例 4. 常见使用场景 5. 注意事项 注意:由于用户要求使用中文,并且所有数学公式使用LaTeX格式,我们在示例中会使用代码块展示SQL语句,并在适当的地方用中文解释。 </think> ### 窗口函数 `SUM() OVER (PARTITION BY ...)` 详解 #### 1. **基本语法结构** ```sql SUM(column) OVER ( PARTITION BY partition_expression ORDER BY sort_expression [ASC|DESC] [ROWS/RANGE BETWEEN frame_start AND frame_end] ) ``` - **`SUM(column)`**:对指定列进行求和 - **`PARTITION BY`**:将数据分割为独立的分组(类似`GROUP BY`但保留明细行)[^1][^4] - **`ORDER BY`**:定义组内计算顺序(影响累计计算方向)[^2] - **`ROWS/RANGE`**:可选子句,定义计算窗口范围[^1][^3] #### 2. **核心功能场景** | 场景 | SQL 示例 | 效果说明 | |------|----------|----------| | **分组累计求和** | `SUM(sales) OVER(PARTITION BY product)` | 按产品分组计算销售总额(每行显示该产品总和) | | **滚动累计求和** | `SUM(sales) OVER(PARTITION BY dept ORDER BY date)` | 按部门+日期顺序计算累计销售额[^2] | | **自定义范围求和** | `SUM(sales) OVER(ORDER BY date ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)` | 计算当前行及前后相邻行的销售和 | #### 3. **完整使用示例** ```sql SELECT employee_id, department, sale_date, daily_sales, -- 部门销售总额(每行相同) SUM(daily_sales) OVER(PARTITION BY department) AS dept_total, -- 部门内按日期累计销售额 SUM(daily_sales) OVER( PARTITION BY department ORDER BY sale_date ) AS running_total, -- 当前员工在部门内销售占比 daily_sales / SUM(daily_sales) OVER(PARTITION BY department) * 100 AS sales_percent FROM sales_records; ``` #### 4. **关键参数说明** - **`PARTITION BY NULL`** 全表作为单一分区:`SUM(sales) OVER()` → 全表销售总和 - **多字段分区** `PARTITION BY year, region` → 按年份和地区双重分组 - **窗口帧控制** ```sql ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -- 从首行到当前行(默认)[^3] ROWS BETWEEN 2 PRECEDING AND CURRENT ROW -- 当前行+前2行 RANGE BETWEEN INTERVAL '7' DAY PRECEDING AND CURRENT ROW -- 近7天范围 ``` #### 5. **与 GROUP BY 的对比** | 特性 | 窗口函数 | GROUP BY | |------|----------|----------| | **输出行数** | 保持原表行数 | 分组合并为单行 | | **明细可见性** | 可同时显示明细和聚合结果 | 明细不可见 | | **多聚合层级** | 单SQL语句实现多层聚合 | 需多次JOIN或子查询 | > 💡 **适用场景**:需保留明细数据的同时展示分组聚合结果,如计算累计占比、移动平均值、排名等分析场景[^1][^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值