从时间戳列中选择日期范围

4 sql postgresql timestamp date-range

目前我的表中有一列用于存储日期和时间.该列的数据类型是没有时区的时间戳.所以它有格式的价值'2011-09-13 11:03:44.537'.

我需要检索与日期有关的行.如果我使用:

select * from table where mdate >= '2011-09-13 11:03:44.537'
                      and mdate <= '2011-09-12 11:03:44.537'
Run Code Online (Sandbox Code Playgroud)

它将提供介于"2011-09-13 11:03:44.537"和"2011-09-12 11:03:44.537"之间的值.

但如果我要去:

select * from table where mdate >= '2011-09-13 00:00:00.0'
                      and mdate <= '2011-09-12 00:00:00.0'
Run Code Online (Sandbox Code Playgroud)

没有日期,月份和秒,它没有显示任何行.

如何根据日期从该表中获取值(仅限日期,忽略小时,分钟和秒)?

甚至,该列具有带时间戳的日期,我只需要使用日期搜索它们(忽略时间戳或将小时,分钟和秒数0'2011-09-13 00:00:00.0').

Erw*_*ter 5

如果要将timestamp字段的值强制转换为date,如另一个答案所示,性能将降低,因为列中的每个值都需要进行转换以进行比较,并且不能使用简单索引.您必须在表达式上创建一个特殊索引,如下所示:

CREATE INDEX some_idx ON tbl (cast(mdate AS date));
Run Code Online (Sandbox Code Playgroud)

在这种情况下,查询也应简化为:

SELECT * FROM tbl WHERE mdate::date = '2011-09-12'::date; -- 2nd cast optional
Run Code Online (Sandbox Code Playgroud)

但是,据我所知,您的问题在查询中是一个简单的错字/思考:
切换了上下边界.尝试:

SELECT * FROM tbl WHERE mdate >= '2011-09-12 00:00:00.0'
                  AND   mdate <= '2011-09-13 00:00:00.0';
Run Code Online (Sandbox Code Playgroud)

或者,为了简化语法并更精确:

SELECT * FROM tbl WHERE mdate >= '2011-09-12 00:00'
                  AND   mdate <  '2011-09-13 00:00';
Run Code Online (Sandbox Code Playgroud)
  • 没有必要拼出秒数和0分数.
  • 您不想包含2011-09-13 00:00,因此请使用<而不是<=.
    不要BETWEEN在这里使用,出于同样的原因:

    WHERE mdate BETWEEN '2011-09-12 00:00' AND '2011-09-13 00:00'
    Run Code Online (Sandbox Code Playgroud)

    这将包括第二天的00:00.

另请注意,timestamp [without time zone]根据您当前的时区设置解释类型列.日期部分取决于该设置,该设置通常应按预期工作.更多细节:
在Rails和PostgreSQL中完全忽略时区