PostgreSQL-筛选日期范围

52

我是一名SQL开发人员,大部分时间都花在MSSQL上。我正在寻找更好的方法来过滤PostgreSQL数据库中“无时区时间戳”字段。

我正在使用:

Where 
DateField >= '2010-01-01' and 
DateField < '2012-01-01'

但是考虑到我不是语法方面的专家,我必须认为还有更好的方法。

有什么建议吗?谢谢。


2
那有什么问题呢?你可以使用between 2010-01-012012-01-01,但实际上几乎是一样的。在MSSQL中是否有更好的方法(我从未使用过)? - Andre
1
@Andre 最好明确指定日期格式。 - Ihor Romanchenko
没关系,只是运行时间有点长。我确保该字段上有索引,但它比我惯常的要花费更多时间。 - Rob S
我从来没有遇到过像那样比较日期的问题,而且我通常不索引我的日期。@RobS 你在处理非常庞大的数据量吗?你在把一堆表连接在一起吗? - Andre
我继承了一个表。我预计会返回大约3-4百万行。 - Rob S
5个回答

90
您的解决方案很好。如果日期是文字,我更喜欢这种写法:
WHERE datefield >= '2010-01-01 00:00:00' 
 AND  datefield <  '2012-01-01 00:00:00'

这样做的效果完全相同,但更易于维护,因为它清楚地表明每个文本字符串“date”都是一个时间戳,而不是日期。例如,假设有时有人将您的查询更改为以下内容:

    AND  datefield <=  '2012-01-01'

...期望(但失败了)在查询中包含完整的日期“2012-01-01”。使用后一种语法,意图更加清晰,避免了这种混淆。

为了使其更加清晰(也许有点啰嗦),您可以进行显式转换:

WHERE datefield >= '2010-01-01 00:00:00'::timestamp 
 AND  datefield <  '2012-01-01 00:00:00'::timestamp

在这里,我不会使用to_date(),原因类似(可能存在数据类型混淆),也不会使用to_timestamp()(它返回timestamptz)。

顺便说一下,我已经修改了大小写以符合推荐规范(关键字大写,标识符小写)。


3
如果你使用'2010-01-01 00:00:00'::timestamp作为开始日期时间,'2010-01-01 24:00:00'::timestamp作为结束日期时间,那么你可以使用BETWEEN。 - thisfeller

18

对于日期间隔,您可以使用类似以下的内容:

WHERE DateField BETWEEN to_date('2010-01-01','YYYY-MM-DD') 
                    AND to_date('2010-01-02','YYYY-MM-DD')

它更短(您不需要重复DateField),并且具有明确的日期格式。

对于每天/每小时/每月/每年,您可以使用:

WHERE date_trunc('day',DateField) = to_date('2010-01-01','YYYY-MM-DD')

“between” 不同于 “>= 和 <”,因为它包括两端。 - Clodoaldo Neto
2
@ClodoaldoNeto 对于时间戳(如问题中所提到的),差异在一毫秒之内。 - Ihor Romanchenko

5

我赞同leonbloy的观点,使用这个会使代码更易读和清晰。

WHERE datefield >= '2010-01-01 00:00:00'::timestamp 
AND  datefield <  '2012-01-01 00:00:00'::timestamp

5
您可以使用BETWEEN来简单查询,只要您的列名是TIMESTAMP类型且不是"timestamp"。例如:SELECT * FROM table WHERE column BETWEEN '2018-12-30 02:19:34' AND '2018-12-30 02:25:34'。这适用于日期和日期时间。

2

如果您想筛选月份或天数等内容,也可以使用间隔时间。示例如下:

datefield < current_date + interval '1 months'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接