如何在SQL中统计日期范围内的重复申请记录?
解决3天内同一申请人重复申请同一职位的问题
嘿,我来帮你搞定这个扩展统计范围的问题!你之前的代码只处理了同一天的重复申请,现在要改成3天内的日期窗口,这里有两种实用的方法,我给你详细拆解下:
方法1:自连接(Self-Join)—— 兼容性拉满
这种方法几乎适用于所有SQL数据库,核心思路是把表和自己做关联,匹配同一个申请人、同一个职位,且申请日期差在3天以内的记录,同时避免重复统计(比如A→B和B→A不会被算作两组)。
代码示例(MySQL版本)
-- 第一步:找出所有符合3天内重复申请的记录对 SELECT a.ApplicantID, a.ApplicationDate AS 首次申请日期, b.ApplicationDate AS 重复申请日期, a.JobDescription FROM Applications a JOIN Applications b ON a.ApplicantID = b.ApplicantID AND a.JobDescription = b.JobDescription AND b.ApplicationDate > a.ApplicationDate -- 避免反向重复配对 AND b.ApplicationDate <= DATE_ADD(a.ApplicationDate, INTERVAL 3 DAY); -- 第二步:统计每个申请人+职位组合的重复次数 SELECT ApplicantID, JobDescription, COUNT(*) AS 3天内重复次数 FROM ( SELECT a.ApplicantID, a.JobDescription FROM Applications a JOIN Applications b ON a.ApplicantID = b.ApplicantID AND a.JobDescription = b.JobDescription AND b.ApplicationDate > a.ApplicationDate AND b.ApplicationDate <= DATE_ADD(a.ApplicationDate, INTERVAL 3 DAY) ) AS 重复配对表 GROUP BY ApplicantID, JobDescription HAVING 3天内重复次数 >= 1;
如果是PostgreSQL,只需要把日期函数换成a.ApplicationDate + INTERVAL '3 days'即可。
方法2:窗口函数(Window Functions)—— 高效简洁
如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server),这种方法会更高效,尤其适合数据量大的场景。它会在每个申请人+职位的分组里,直接统计3天窗口内的申请总数。
代码示例(通用版本)
-- 先给每条记录标记出3天窗口内的申请总数 WITH 带窗口统计的申请表 AS ( SELECT *, COUNT(*) OVER ( PARTITION BY ApplicantID, JobDescription ORDER BY ApplicationDate RANGE BETWEEN INTERVAL 0 DAY PRECEDING AND INTERVAL 3 DAY FOLLOWING ) AS 3天内申请总数 FROM Applications ) -- 筛选出存在重复申请的记录(窗口内申请数≥2) SELECT ApplicantID, ApplicationDate, JobDescription, 3天内申请总数 FROM 带窗口统计的申请表 WHERE 3天内申请总数 >= 2; -- 如果要统计有多少个重复的申请人+职位组合 SELECT COUNT(DISTINCT CONCAT(ApplicantID, '-', JobDescription)) AS 重复组合数 FROM 带窗口统计的申请表 WHERE 3天内申请总数 >= 2;
小提醒
不同数据库的窗口函数语法有细微差异,比如SQL Server需要把日期转成数值型(比如自某个基准日的天数)来用RANGE BETWEEN,或者改用ROWS BETWEEN结合日期过滤,根据你的数据库调整即可。
和你原有代码的区别
你原来的代码是按ApplicantID, ApplicationDate, JobDescription精确分组统计同一天的重复,现在的方法打破了日期的精确匹配,换成了3天范围的关联/窗口统计,核心是从“同一天”扩展到了“连续3天窗口”。
内容的提问来源于stack exchange,提问作者Rhys Chellew
相关产品推荐
相关产品推荐

