Z
ZHANK
分组与聚合

窗口函数入门

掌握 ROW_NUMBER、RANK、PARTITION BY、OVER

窗口函数入门

普通聚合函数把多行压成一行。窗口函数保持每行都在,同时附加一个基于"窗口"的计算结果——比如给每行加上排名、累计值、上下行对比。

学完本章你将: 掌握 ROW_NUMBER、RANK、PARTITION BY。


和聚合函数的区别

sql
-- 聚合:每人只剩一行(城市 + 该城市人数)
SELECT city, COUNT(*) FROM users GROUP BY city;

-- 窗口:每个人都在,额外多一列"该城市有多少人"
SELECT name, city,
    COUNT(*) OVER (PARTITION BY city) AS 同城人数
FROM users;

ROW_NUMBER —— 编序号

sql
-- 按年龄排名
SELECT name, age,
    ROW_NUMBER() OVER (ORDER BY age DESC) AS 排名
FROM users;

-- 分组内排名(每个城市内排名)
SELECT name, city, age,
    ROW_NUMBER() OVER (PARTITION BY city ORDER BY age DESC) AS 城市内排名
FROM users;

RANK vs DENSE_RANK

sql
SELECT name, score,
    RANK() OVER (ORDER BY score DESC) AS rank_,        -- 1,2,2,4...
    DENSE_RANK() OVER (ORDER BY score DESC) AS dense_   -- 1,2,2,3...
FROM students;
  • RANK:并列后跳过(1,2,2,4)
  • DENSE_RANK:并列不跳过(1,2,2,3)

窗口函数语法

sql
函数名() OVER (
    PARTITION BY 分组列    -- 怎么分窗口(可选)
    ORDER BY 排序列        -- 窗口内怎么排(可选)
)

💡 窗口函数不能用在 WHERE 中。 它是在 SELECT 阶段计算的,WHERE 在它之前。要过滤窗口函数的结果,用子查询或 CTE。