在此查询中:
Select * from table where future_date - CURRENT_DATE <= '10';
返回10天或更短的时间间隔。
如何添加两个参数?例如:
Select * from table where future_date - CURRENT_DATE <= '10' AND >= '30';
我已经尝试过:
Select * from table where future_date - CURRENT_DATE BETWEEN '10' AND '30'
但它没有用。
答案 0 :(得分:3)
SELECT *
FROM mytable
WHERE future_date BETWEEN CURRENT_DATE + '10 days'::INTERVAL AND CURRENT_DATE + '30 days'::INTERVAL
答案 1 :(得分:2)
您的第一个示例是语法上的废话,但您的秒有效如果您的列实际上是date
,那么(大部分)会按预期工作列名暗示:
Select * from table where future_date - CURRENT_DATE BETWEEN '10' AND '30'
表达式future_date - CURRENT_DATE
的结果取决于future_date
的实际未公开数据类型。
如果future_date
是date
,则future_date - CURRENT_DATE
的结果是integer
数字,表示天数的差异,以及您的无类型字符串文字'10'和'30'
投放到integer
:查询有效(即使效率低)并且涵盖21天(不是20天) )。
如果future_date
是timestamp
(or timestamptz
),则结果为interval
,表示时间间隔。在这种情况下使用CURRENT_DATE
会很奇怪但合法。假设当天00:00时,该值被强制为timestamp
(或timestamptz
)。
但是,您的无类型字符串文字现在被转换为interval
且没有任何给定的时间单位an integer
number defaults to meaning seconds,因此谓词有效地从中选择10到30秒的窄时间范围
亲眼看看:
SELECT '10'::interval
interval
---------
'00:00:10'
澄清错误信息:CURRENT_DATE
就好了。它是一个标准的SQL函数,由于遗留原因没有括号,在Postgres内部实现为now()::date
。两者都是STABLE
函数(所以&#34;运行时常量&#34;)。您的表达式存在的其他问题:效率非常低,因为不是sargable 。
对于 date
列:
SELECT *
FROM mytable
WHERE future_date BETWEEN CURRENT_DATE + 10
AND CURRENT_DATE + 30; -- 21 days (!)
您只需将integer
添加到date
即可添加/减去天数。
这为您提供了21天(不是20天)的范围,因为BETWEEN
包含下限和上限。通常,您希望包含较低但排除的上限。
对于 timestamp
或 timestamptz
列:
SELECT *
FROM mytable
WHERE future_date >= now() + interval '10 days'
AND future_date < now() + interval '30 days'; -- 20 days (!)
这涵盖了20天(!)的时间范围,分布在21个日历日(!),除非您从午夜开始完全,在这种情况下,完全涵盖了20个日历日。
通常情况下,您希望使用日历日作为界限:
...
WHERE future_date >= (CURRENT_DATE + 10)
AND future_date < (CURRENT_DATE + 30);
或timestamp
或timestamptz
now()::date + interval '10 days' -- returns timestamp
CURRENT_DATE + interval '10 days' -- returns timestamp
date_trunc('day', now()) + interval '10 days' -- returns timestamptz
数据类型强制转换为future_date
的类型,因此适用于任何一种类型。
请注意, date 由其时区定义。因此,这些表达式取决于会话的当前timezone
设置。
现在应该很明显,为什么BETWEEN .. AND ..
通常错误 带有时间戳。大多数情况下,您希望包含下限,排除上限。 BETWEEN .. AND ..
将在最后一个示例中包含第二天的00:00
,从而为第21天开启一个角落案例。
相关: