如何删除可转换为date类型的varchar列数据行?
问题分析
你之前的两种方法都存在问题:
- 字符串直接比较
value > '01.01.1970'是按字符ASCII码顺序判断的,比如'1'的首字符'1'比'0'ASCII码大,所以会被误选,不符合日期的实际大小逻辑。 - 直接
cast(value as date)会因为无法转换的行(如'1.2')抛出异常,导致查询中断。
核心需求是筛选能安全转换为日期且日期大于1970-01-01的行,需要用数据库的安全转换函数先判断合法性,再筛选。
解决方案
以下是主流数据库的实现方式:
MySQL/MariaDB
使用STR_TO_DATE按指定格式转换,转换失败返回NULL,以此筛选合法行:
SELECT * FROM `values` WHERE STR_TO_DATE(value, '%d.%m.%Y') IS NOT NULL AND STR_TO_DATE(value, '%d.%m.%Y') > '1970-01-01';
注:
%d.%m.%Y对应你的日期格式日.月.年,如果格式不同需要调整。
PostgreSQL
使用TRY_CAST或带错误处理的TO_DATE:
-- 方法1:TRY_CAST 自动处理转换失败 SELECT * FROM "values" WHERE TRY_CAST(value AS DATE) IS NOT NULL AND TRY_CAST(value AS DATE) > '1970-01-01'; -- 方法2:指定格式的TO_DATE(PostgreSQL 12+) SELECT * FROM "values" WHERE TO_DATE(value, 'DD.MM.YYYY') ON ERROR NULL IS NOT NULL AND TO_DATE(value, 'DD.MM.YYYY') > '1970-01-01';
SQL Server
用TRY_CAST或TRY_CONVERT实现安全转换:
-- 通用TRY_CAST SELECT * FROM values WHERE TRY_CAST(value AS DATE) IS NOT NULL AND TRY_CAST(value AS DATE) > '1970-01-01'; -- 指定格式的TRY_CONVERT(104对应dd.mm.yyyy) SELECT * FROM values WHERE TRY_CONVERT(DATE, value, 104) IS NOT NULL AND TRY_CONVERT(DATE, value, 104) > '1970-01-01';
Oracle
使用VALIDATE_CONVERSION判断合法性,再转换筛选:
SELECT * FROM values WHERE VALIDATE_CONVERSION(value AS DATE, 'DD.MM.YYYY') = 1 AND TO_DATE(value, 'DD.MM.YYYY') > DATE '1970-01-01';
内容的提问来源于stack exchange,提问作者AbrA
相关产品推荐
相关产品推荐

