Eds*_*ues 3 sql postgresql date-range
在这个查询中:
Select * from table where future_date - CURRENT_DATE <= '10';
它返回 10 天或更短的间隔。
如何添加两个参数?例子:
Select * from table where future_date - CURRENT_DATE <= '10' AND >= '30';
Run Code Online (Sandbox Code Playgroud)
我已经尝试过:
Select * from table where future_date - CURRENT_DATE BETWEEN '10' AND '30'
Run Code Online (Sandbox Code Playgroud)
但它不起作用。
您的第一个示例在语法上是无稽之谈,但您的第二个示例是有效的,并且如果您的列实际上date就像列名称所暗示的那样,则(大部分)会按预期工作:
Select * from table where future_date - CURRENT_DATE BETWEEN '10' AND '30'
Run Code Online (Sandbox Code Playgroud)
该表达式的结果future_date - CURRENT_DATE取决于实际,未公开的数据类型的future_date。
如果future_date是 a date,则结果future_date - CURRENT_DATE是一个integer表示天数差异的数字,并且您的无类型字符串文字 '10'和'30'被强制转换为integer每个分配强制转换:查询有效(即使效率低下)并涵盖 21 天(不是 20 天)的范围。
如果future_date是timestamp(或timestamptz),则结果是interval表示时间间隔。CURRENT_DATE在这种情况下使用会很奇怪但合法。该值被强制为timestamp(或timestamptz)假设为一天中的 00:00 小时。
但是,您的无类型字符串文字现在投射到interval并且没有任何给定的时间单位,一个integer数的装置秒通过默认,所以谓词有效地从选择的10到30秒的时间窄帧现在。
你自己看:
SELECT '10'::interval
interval
---------
'00:00:10'
Run Code Online (Sandbox Code Playgroud)
为了澄清误传:CURRENT_DATE就好了。由于遗留原因,它是一个没有括号的标准 SQL 函数。曾经now()::date在 Postgres 内部实现。两者都是STABLE函数(所以是“运行时常量”)。你的表达式的另一个问题是:它非常低效,因为它不是sargable。
对于date列:
SELECT *
FROM mytable
WHERE future_date BETWEEN CURRENT_DATE + 10
AND CURRENT_DATE + 30; -- 21 days (!)
Run Code Online (Sandbox Code Playgroud)
您可以添加integer到date添加/减去天数。
这为您提供了 21(不是 20!)天的范围,因为BETWEEN 包括下限和上限。通常,您希望包括下限但排除上限。
对于 atimestamp 或timestamptz列:
SELECT *
FROM mytable
WHERE future_date >= now() + interval '10 days'
AND future_date < now() + interval '30 days'; -- 20 days (!)
Run Code Online (Sandbox Code Playgroud)
这涵盖了 20 天 (!) 跨 21 个日历日 (!) 的时间范围,除非您恰好从午夜开始,在这种情况下,完全覆盖了 20 个日历日。
通常,您希望以日历日为界限:
...
WHERE future_date >= (CURRENT_DATE + 10)
AND future_date < (CURRENT_DATE + 30);
Run Code Online (Sandbox Code Playgroud)
这些表达式或两种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
Run Code Online (Sandbox Code Playgroud)
数据类型被强制转换为 的类型future_date,因此它适用于任一类型。
请注意,日期由其时区定义。所以这些表达式取决于timezone会话的当前设置。
它现在应该是显而易见的,为什么BETWEEN .. AND ..是典型的错误带有时间戳。大多数情况下,您希望包括下限并排除上限。BETWEEN .. AND ..将00:00在最后一个示例中包括第二天,从而为第 21 天打开一个角落案例。
有关的:
| 归档时间: |
|
| 查看次数: |
13999 次 |
| 最近记录: |