SQL 窗口函数(Window Functions) 用于在“一组相关行”上进行计算,同时不把行合并成一行(和普通聚合函数不同)。常见用途:排名、累计求和、移动平均、前后行比较等。
函数名(列)
OVER (
[PARTITION BY 分组列]
[ORDER BY 排序列]
[窗口范围]
)
关键点:
OVER():必须有,表示“窗口”PARTITION BY:类似 GROUP BY,但不合并行ORDER BY:决定计算顺序ROWS BETWEEN 1 PRECEDING AND CURRENT ROWROW_NUMBER() OVER (ORDER BY score DESC) -- 1,2,3,4
RANK() OVER (ORDER BY score DESC) -- 1,1,3
DENSE_RANK() OVER (ORDER BY score DESC) -- 1,1,2
示例:
SELECT
name,
score,
RANK() OVER (ORDER BY score DESC) AS rk
FROM students;
SUM(salary) OVER (PARTITION BY dept) -- 部门工资总和
AVG(salary) OVER (PARTITION BY dept) -- 部门平均工资
COUNT(*) OVER (PARTITION BY dept)
示例:
SELECT
name,
dept,
salary,
AVG(salary) OVER (PARTITION BY dept) AS dept_avg
FROM employees;
SUM(amount) OVER (
PARTITION BY user_id
ORDER BY date
) -- 累计求和
移动平均:
AVG(price) OVER (
ORDER BY date
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
)
LAG(salary) OVER (ORDER BY hire_date) -- 上一行
LEAD(salary) OVER (ORDER BY hire_date) -- 下一行
示例:
SELECT
name,
salary,
LAG(salary) OVER (ORDER BY salary) AS prev_salary
FROM employees;
SELECT
dept,
name,
salary,
RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS dept_rank,
SUM(salary) OVER (PARTITION BY dept) AS dept_total
FROM employees;
结果特点:
| 对比点 | GROUP BY | 窗口函数 |
|---|---|---|
| 行数 | 减少 | 不变 |
| 是否保留明细 | 否 | 是 |
| 典型用途 | 汇总 | 排名/累计 |
✅ PostgreSQL
✅ MySQL 8.0+
✅ SQL Server
✅ Oracle
✅ SQLite 3.25+
如果你有具体业务场景(比如:销售排名、用户留存、同比环比),我可以帮你写可直接用的 SQL。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。