Postgres:如何将动态生成的日期传入WHERE子句
高效解决方案:替代字符串拼接的日期查询方法
方案1:直接使用日期范围查询(性能最优)
完全没必要生成字符串形式的日期序列,直接用日期范围条件可以完美匹配date类型字段,还能利用created_date上的索引,是最高效的写法:
SELECT * FROM t1 WHERE created_date >= '2022-10-01' AND created_date <= '2022-10-05';
如果created_date是datetime类型(包含时分秒),为了避免漏掉当天的记录,可以调整为:
SELECT * FROM t1 WHERE created_date >= '2022-10-01' AND created_date < '2022-10-06'; -- 取次日凌晨作为上限
方案2:生成原生日期序列(适用于精确匹配离散日期场景)
如果确实需要针对离散日期列表查询(比如中间有跳过的日期,但你的连续日期场景下方案1更合适),可以用递归CTE生成原生date类型的序列,再通过子查询关联:
SQL Server 写法
DECLARE @last_run_date DATE = '2022-10-01'; DECLARE @current_date DATE = '2022-10-05'; WITH DateSequence AS ( SELECT @last_run_date AS seq_date UNION ALL SELECT DATEADD(DAY, 1, seq_date) FROM DateSequence WHERE seq_date < @current_date ) SELECT * FROM t1 WHERE created_date IN (SELECT seq_date FROM DateSequence);
MySQL 写法
SET @last_run_date = '2022-10-01'; SET @current_date = '2022-10-05'; WITH RECURSIVE DateSequence AS ( SELECT @last_run_date AS seq_date UNION ALL SELECT DATE_ADD(seq_date, INTERVAL 1 DAY) FROM DateSequence WHERE seq_date < @current_date ) SELECT * FROM t1 WHERE created_date IN (SELECT seq_date FROM DateSequence);
PostgreSQL 写法
WITH DateSequence AS ( SELECT generate_series( '2022-10-01'::DATE, '2022-10-05'::DATE, '1 day'::INTERVAL )::DATE AS seq_date ) SELECT * FROM t1 WHERE created_date IN (SELECT seq_date FROM DateSequence);
原方案问题说明
原方案拼接的字符串属于varchar类型,数据库会隐式转换created_date为字符串去匹配,不仅会导致created_date上的索引失效,还可能因日期格式不兼容出现匹配错误。上述方案均使用原生date类型进行匹配,避免了类型转换的性能损耗和错误风险。
内容的提问来源于stack exchange,提问作者rev gan
相关产品推荐
相关产品推荐

