Postgres日期检查-is_Date fn短路



我在一个表中有一组记录,其中一些记录的日期无效。我想忽略那些无效的记录,并对其余的记录进行检查。我构建了一个如下的查询,但我觉得它不起作用。

select * from tbl_name i
where is_date(i.dob) and i.dob::date > CURRENT_DATE;

我知道sql不会短路,所以它也会考虑无效记录,并以超出范围的日期/时间结束。请帮助我更改此查询,这样我就可以消除无效日期,只对有效日期进行日期比较。

Postgres中不能保证短路。两者都不在";普通的";WHERE子句,在使用派生表(from (select ...) where ...(时也不使用。强制分两步进行评估的一种方法是物化公共表表达式:

with data as materialized (
select * 
from tbl_name i
where is_date(i.dob)
)
select *
from data
where dob::date > CURRENT_DATE;

materialized关键字防止优化器将外部查询的条件推送到CTE中。

显然,这假设is_date()永远不会返回误报

WHERE中使用CASE来区分有效日期和无效日期,并对有效日期运行>比较,否则返回FALSE

create or replace function is_date(s varchar) returns boolean as $$
begin
if s is null then
return false;
end if;
perform s::date;
return true;
exception when others then
return false;
end;
$$ language plpgsql;
create table date_str (id integer, dt_str varchar);
insert into date_str values (1, '2022-11-02'), (2, '1234'), (3, '2022-12-03');
insert into date_str values (4, 'xyz'), (5, '2022-01-01'), (6, '2023-02-02');
select * from date_str;
id |   dt_str   
----+------------
1 | 2022-11-02
2 | 1234
3 | 2022-12-03
4 | xyz
5 | 2022-01-01
6 | 2023-02-02
select current_date;
current_date 
--------------
11/02/2022

SELECT
*
FROM
date_str
WHERE
CASE WHEN is_date (dt_str) = 't' THEN
dt_str::date > CURRENT_DATE
ELSE
FALSE
END;
id |   dt_str   
----+------------
3 | 2022-12-03
6 | 2023-02-02

最新更新