场景 1:分组内排名(Top N 问题) 最常见
需求:查找每个部门薪水前三名的员工信息。
为什么用它:如果不用窗口函数,你不得不在 Java 里查出所有数据再用 Stream 分组排序,或者在 SQL 里写极其复杂的自连接。
核心函数:ROW_NUMBER()、RANK()、DENSE_RANK()

SQL
-- 给每个部门的员工按薪水降序打上排名序号
SELECT 
    emp_no, 
    dept_no, 
    salary,
    ROW_NUMBER() OVER(PARTITION BY dept_no ORDER BY salary DESC) as rk
FROM salaries;
-- 外层再套一个 SELECT 查 rk <= 3 即可拿到 Top 3


场景 2:跨行比较(和上一行/下一行对比)
需求:计算某个员工这个月的薪水比上个月涨了多少(环比增长)。
为什么用它:关系型数据库天然是一行一行独立的,正常情况下这一行不知道上一行的数据。窗口函数打破了这个限制。
核心函数:LAG()(获取上一行)、LEAD()(获取下一行)

SQL
SELECT 
    emp_no,
    salary,
    LAG(salary, 1) OVER(PARTITION BY emp_no ORDER BY from_date) as prev_salary
FROM salaries;


场景 3:累计求和 / 移动平均
需求:计算某个公司从 1 月到 12 月的累计总收入(1月是1月的钱,2月是1+2月的钱,3月是1+2+3月的钱)。
核心函数:SUM() OVER(ORDER BY ...)

SQL
SELECT 
    month,
    revenue,
    SUM(revenue) OVER(ORDER BY month) as cumulative_revenue
FROM sales;


场景 4:既看明细,又看全局聚合
需求:查询所有员工的信息,并在最后加一列显示“该员工薪水与公司平均薪水的差值”。
为什么用它:避免写繁琐的子查询 (SELECT AVG(salary) FROM salaries) 再 JOIN 起来。

SQL
SELECT 
    emp_no,
    salary,
    AVG(salary) OVER() as company_avg_salary, -- 整个公司的平均薪水
    salary - AVG(salary) OVER() as diff
FROM salaries;


本题答案
SELECT
    emp_no,
    salary,
    SUM(salary) OVER (
        ORDER BY
            emp_no
    ) AS running_total
FROM
    salaries
WHERE
    to_date = '9999-01-01'