CASE WHEN处理不同格式日期报错,如何解决?
问题分析
你遇到的两个错误本质是**col3中存在非NULL但格式/值无效的日期字符串**(比如包含xxxx-xx-00这种天数为0的非法值,或者其他不符合yyyy-mm-dd规范的内容)。即便你判断了col3 is not null,这些坏数据依然会触发日期转换失败。
解决方案
1. 使用数据库自带的安全日期转换函数(推荐)
主流数据库都提供了转换失败时返回NULL的安全函数,能避免报错同时自动跳过无效数据:
PostgreSQL
select *, case when try_cast(col3 as date) > col2 then 'abc' else col1 end as var1 from my_t;
try_cast自动处理NULL和无效值,转换失败返回NULL,条件不成立时走else分支,无需额外判断col3 is not null
Oracle 12c+
select *, case when to_date(col3 default null on conversion error, 'yyyy-mm-dd') > col2 then 'abc' else col1 end as var1 from my_t;
Oracle 12.2+支持default ... on conversion error语法,转换失败返回NULL
SQL Server
select *, case when try_convert(date, col3) > col2 then 'abc' else col1 end as var1 from my_t;
MySQL
select *, case when str_to_date(col3, '%Y-%m-%d') > col2 then 'abc' else col1 end as var1 from my_t;
str_to_date转换失败时返回NULL,自动跳过无效数据
2. 正则校验+转换(兼容老版本数据库)
如果数据库不支持安全转换函数,可以用正则先过滤格式合法的col3值:
select *, case when col3 ~ '^\d{4}-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$' and cast(col3 as date) > col2 then 'abc' else col1 end as var1 from my_t;
注:正则仅能校验格式,无法判断逻辑上不存在的日期(比如2023-02-30),优先推荐安全转换函数
3. 清理脏数据(可选)
若这些无效数据是业务脏数据,建议先排查清理:
-- 先查询所有无效的col3值 select col3 from my_t where col3 is not null and try_cast(col3 as date) is null; -- 根据需求删除或更新脏数据 delete from my_t where col3 is not null and try_cast(col3 as date) is null;
内容的提问来源于stack exchange,提问作者Uk rain troll
相关产品推荐
相关产品推荐

