SQL需求:按客户每年提取3月最早日期的完整数据行
提取每位客户每年3月最早日期的完整记录
示例数据
假设我们有一张存储客户记录的表customer_records,简化结构及数据如下:
| customer_id | record_date | other_field |
|---|---|---|
| 101 | 2023-03-05 | A |
| 101 | 2023-03-02 | B |
| 101 | 2022-03-10 | C |
| 102 | 2023-03-01 | D |
| 102 | 2023-03-03 | E |
解决方案
使用窗口函数ROW_NUMBER()是最直接的方式,它可以在不聚合的前提下,为每个客户的年度3月记录按日期排序,取最早的那一行完整数据。
标准SQL写法
WITH ranked_records AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY customer_id, EXTRACT(YEAR FROM record_date) ORDER BY record_date ASC ) AS rn FROM customer_records WHERE EXTRACT(MONTH FROM record_date) = 3 ) SELECT customer_id, record_date, other_field -- 替换为实际需要的所有字段 FROM ranked_records WHERE rn = 1;
数据库兼容版本(以MySQL为例)
如果使用MySQL,可替换日期函数为YEAR()和MONTH():
WITH ranked_records AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY customer_id, YEAR(record_date) ORDER BY record_date ASC ) AS rn FROM customer_records WHERE MONTH(record_date) = 3 ) SELECT customer_id, record_date, other_field FROM ranked_records WHERE rn = 1;
预期结果
执行上述查询后,会得到每个客户每年3月最早日期对应的完整记录:
| customer_id | record_date | other_field |
|---|---|---|
| 101 | 2023-03-02 | B |
| 101 | 2022-03-10 | C |
| 102 | 2023-03-01 | D |
关键逻辑说明
PARTITION BY customer_id, EXTRACT(YEAR FROM record_date):将数据按客户ID和年份分组,确保每个客户的年度3月记录单独处理ORDER BY record_date ASC:对每组内的记录按日期升序排序,最早的记录会被标记为序号1WHERE EXTRACT(MONTH FROM record_date) = 3:提前筛选出3月的记录,减少不必要的计算
内容的提问来源于stack exchange,提问作者triple_r
相关产品推荐
相关产品推荐

