跳到主要内容

COUNT OVER 窗口函数详解

一、一句话理解

COUNT() OVER() 统计每个窗口范围内的行数,可以用来做累计计数、分组行号和累计达标次数。

二、函数语法

COUNT(列名) OVER (PARTITION BY 分组列 ORDER BY 排序列 窗口帧)
COUNT(*) OVER (...) -- 统计所有行(含 NULL)

三、真实业务场景

场景1:每个用户的第几次购买

SELECT user_id, order_date,
COUNT(*) OVER (PARTITION BY user_id ORDER BY order_date) AS order_seq
FROM orders;
+----------+------------+-----------+
| user_id | order_date | order_seq |
+----------+------------+-----------+
| 1 | 2025-01-05 | 1 |
| 1 | 2025-01-15 | 2 |
| 1 | 2025-02-03 | 3 |
+----------+------------+-----------+

场景2:连续签到天数

累计计数 + 差值法:用 COUNT 统计同一差值组的行数。

SELECT user_id, grp, COUNT(*) AS consecutive_days
FROM (
SELECT user_id, login_date,
DATE_SUB(login_date, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date)) AS grp
FROM user_login
) t
GROUP BY user_id, grp;

四、COUNT vs COUNT(*)

写法行为
COUNT(*) OVER()统计所有行,含 NULL
COUNT(col) OVER()只统计 col 不为 NULL 的行

五、常见坑点

坑:COUNT DISTINCT 不能用于窗口函数

COUNT(DISTINCT col) OVER() 会报错。如果需要在窗口中统计去重数量,需要用子查询或 DENSE_RANK 变通方案。

七、相关面试题

📱关注公众号

「数据仓库技术」文章同步更新,不错过每一篇干货

微信公众号二维码
💬加群交流

备注「数据仓库技术」加入社群,每日一道大厂SQL真题

交流微信二维码

你可能还想看