基于历史分组统计唯一条目数的动态实现需求
按时间分组统计新增唯一值的高效解决方案
针对你需要的「按时间分组,统计每组中从未在之前任何分组出现过的唯一值数量」,我有个非常高效的动态实现方案——不需要手动编写针对每个时间块的子查询,核心思路是先追踪每个值的首次出现时间,再按时间分组统计即可。
核心逻辑拆解
- 第一步:锁定首次出现时间:对每个唯一值,找到它第一次出现在数据集中的时间戳,这一步能帮我们区分哪些值是某个时间点的「新增值」。
- 第二步:分组统计新增数:把第一步得到的结果按时间分组,统计每个时间点对应的首次出现值的数量,这就是该时间分组的新增唯一值数。
示例SQL代码(以MySQL为例)
假设你的表是data_records,时间字段为log_time,值字段为item_id:
-- 用CTE获取每个值的首次出现时间(支持MySQL 8.0+、PostgreSQL、SQL Server等) WITH first_seen AS ( SELECT item_id, MIN(log_time) AS first_appearance FROM data_records GROUP BY item_id ) -- 按首次出现时间分组统计 SELECT first_appearance AS log_time, COUNT(*) AS new_unique_items FROM first_seen GROUP BY first_appearance ORDER BY first_appearance;
用你的示例数据验证
原始数据:
2018-03-25 00:00:00.000, 123
2018-03-25 00:00:00.000, 231
2018-03-26 00:00:00.000, 234
2018-03-26 00:00:00.000, 123
2018-03-27 00:00:00.000, 123
2018-03-27 00:00:00.000, 231
2018-03-27 00:00:00.000, 234
2018-03-27 00:00:00.000, 432
第一步生成的first_seen结果:
| item_id | first_appearance |
|---|---|
| 123 | 2018-03-25 00:00:00 |
| 231 | 2018-03-25 00:00:00 |
| 234 | 2018-03-26 00:00:00 |
| 432 | 2018-03-27 00:00:00 |
最终分组统计后就得到你要的输出:
2018-03-25 00:00:00.000, 2
2018-03-26 00:00:00.000, 1
2018-03-27 00:00:00.000, 1
兼容旧版数据库(无CTE支持)
如果你的数据库不支持CTE(比如MySQL 5.x),可以改用子查询:
SELECT first_appearance AS log_time, COUNT(*) AS new_unique_items FROM ( SELECT item_id, MIN(log_time) AS first_appearance FROM data_records GROUP BY item_id ) AS first_seen GROUP BY first_appearance ORDER BY first_appearance;
这个方案完全动态,不管你的时间序列有多长、有多少个时间分组,都能自动处理,不需要手动调整查询逻辑,性能也很出色,因为只需要两次聚合操作。
内容的提问来源于stack exchange,提问作者rodling
相关产品推荐
相关产品推荐

