求助:同表内筛选间隔30天内的入院日期数据并解决重复问题
解决同一ID下间隔30天内的入院日期筛选问题
方案1:自连接查询(简单直接)
直接通过自连接匹配同一ID下日期间隔≤30天的记录,同时用DISTINCT去除重复数据:
假设你的表名为admissions,日期格式为MM/DD/YYYY,以MySQL语法为例:
SELECT DISTINCT a.ID, a.`Date` FROM admissions a JOIN admissions b ON a.ID = b.ID AND ABS(DATEDIFF(STR_TO_DATE(a.`Date`, '%m/%d/%Y'), STR_TO_DATE(b.`Date`, '%m/%d/%Y'))) <= 30 AND a.`Date` != b.`Date` ORDER BY a.ID, STR_TO_DATE(a.`Date`, '%m/%d/%Y');
STR_TO_DATE负责将字符串格式的日期转为数据库可识别的日期类型ABS(DATEDIFF(...))计算两个日期的天数差并取绝对值,确保前后日期的间隔都能被检测到DISTINCT用于剔除重复出现的记录(比如同一条日期会被多条匹配记录关联)- 排序必须写在最终查询里,视图本身不支持存储排序规则,之前创建视图时加
ORDER BY是无效的,查询视图时再指定ORDER BY即可
方案2:窗口函数(更高效)
用LAG和LEAD函数获取每个日期的前后相邻日期,直接判断间隔是否符合要求:
WITH formatted_dates AS ( SELECT ID, `Date`, STR_TO_DATE(`Date`, '%m/%d/%Y') AS date_obj FROM admissions ), ranked_dates AS ( SELECT ID, `Date`, date_obj, LAG(date_obj) OVER (PARTITION BY ID ORDER BY date_obj) AS prev_date, LEAD(date_obj) OVER (PARTITION BY ID ORDER BY date_obj) AS next_date FROM formatted_dates ) SELECT DISTINCT ID, `Date` FROM ranked_dates WHERE (prev_date IS NOT NULL AND DATEDIFF(date_obj, prev_date) <= 30) OR (next_date IS NOT NULL AND DATEDIFF(next_date, date_obj) <= 30) ORDER BY ID, date_obj;
- 先把字符串日期转成日期类型,再按ID分组、日期排序,用窗口函数获取每条记录的前后日期
- 只要当前日期和前/后日期间隔≤30天,就保留这条记录
DISTINCT同样用来避免重复数据
针对你之前的问题说明
- 视图无法排序:SQL标准中视图不支持存储
ORDER BY规则(除非搭配LIMIT等行限制语句),排序逻辑必须放在查询视图的语句里,比如SELECT * FROM your_view ORDER BY ID, Date; - 关联后重复数据:自连接会产生双向配对(比如A日期匹配B日期,B日期也会匹配A日期),用
DISTINCT或者限制连接条件为a.Date < b.Date再通过UNION ALL补全反向记录,都能解决重复问题,上面的方案已经通过DISTINCT处理了这个问题。
内容的提问来源于stack exchange,提问作者DJT
相关产品推荐
相关产品推荐

