日期分隔符返回越界结果,复杂SQL出院日期过滤问题咨询
问题1:日期分隔符返回超出范围结果的排查与解决
先给你梳理下这个问题的常见原因和解决方向,结合你用的PostgreSQL环境(从public.visit的表结构能看出来),大概率是格式匹配错误或者数据本身有问题:
- 先确认日期字段的原始类型:如果
visit_admit_date/visit_disch_date是varchar类型,可能存在格式不统一的脏数据(比如有的是2017-09-22,有的是09/22/2017),转换时就会触发“超出范围”错误。可以先跑个查询排查:
找出不符合SELECT visit_id, visit_admit_date FROM public.visit WHERE visit_admit_date !~ '^\d{4}-\d{2}-\d{2}$';YYYY-MM-DD格式的记录,先清理或者统一格式。 - 检查日期函数的格式参数:如果你用
to_date/to_char时用错了格式串,比如把原始YYYY-MM-DD格式的日期用MMDDYYYY去解析,肯定会报错。比如错误写法:
正确的应该对应格式串:-- 错误:原始日期带横杠,格式串没匹配分隔符 to_date(visit_admit_date, 'MMDDYYYY')-- 解析YYYY-MM-DD格式的字符串为date类型 to_date(visit_admit_date, 'YYYY-MM-DD') -- 如果字段本身是date类型,直接格式化即可 to_char(visit_admit_date, 'MMDDYYYY') - 排查非法日期值:如果字段是
date类型,但存在2017-13-22(月份13)、2017-02-30(2月30号)这种非法值,也会报错。PostgreSQL 12+可以用is_date函数检查:SELECT visit_id, visit_admit_date FROM public.visit WHERE NOT is_date(visit_admit_date::text);
问题2:SQL过滤出院日期距今超过90天的数据优化
你现在把日期转成MMDDYYYY字符串的做法完全没必要,而且用字符串做日期比较很容易出错(比如字符串12312023会比01012024大,但实际日期是2023年12月31号早于2024年1月1号),直接用日期类型做运算才是正确姿势:
正确的过滤条件写法
如果visit_disch_date是date类型(从你给出的格式看应该是),直接把过滤条件加到WHERE子句里:
SELECT to_char("public".visit.visit_admit_date, 'MMDDYYYY') AS "Visit or Admit Date", to_char("public".visit.visit_disch_date, 'MMDDYYYY') AS "Discharge Date" FROM public.visit WHERE -- 保留出院日期距今不超过90天的记录(即排除超过90天的) "public".visit.visit_disch_date >= CURRENT_DATE - INTERVAL '90 days' AND EXISTS ( SELECT DISTINCT ON ("public".visit.visit_id) "public".procedure_group_cpt_code.pgrpcpt_code::text -- 这里补充你的子查询关联条件,比如: -- FROM public.procedure_group_cpt_code -- WHERE public.procedure_group_cpt_code.visit_id = public.visit.visit_id );
如果visit_disch_date是varchar类型,先转成date类型再比较:
WHERE to_date("public".visit.visit_disch_date, 'YYYY-MM-DD') >= CURRENT_DATE - INTERVAL '90 days' AND EXISTS (...)
为什么不要用字符串比较?
字符串是按字符ASCII码顺序比较的,比如12312023(2023-12-31)的首字符是1,01012024(2024-01-01)的首字符是0,字符串比较时会认为12312023 > 01012024,但实际日期是2023年的更早,完全不符合你的过滤逻辑,所以一定要用原生日期类型做时间运算。
内容的提问来源于stack exchange,提问作者Ya Guy Godzilla
相关产品推荐
相关产品推荐

