PostgreSQL的:有日期时间之间(PostgreSQL: between with datet

2019-07-31 13:57发布

我使用PostgreSQL 8.4.11和发现奇怪的错误。 当我查询:

SELECT "documents_document"."given_on" 
FROM "documents_document" 
WHERE (EXTRACT('month' FROM "documents_document"."given_on") = 1
       AND "documents_document"."given_on" 
       BETWEEN '1-01-01 00:00:00' and '1-12-31 23:59:59.999999') 
ORDER BY "documents_document"."created_on" DESC

我得到的结果:

  given_on  
------------
 2002-01-16
 2011-01-25
 2012-01-12
 2012-01-12
 2012-01-12
 2012-01-20
 2012-01-19
 2012-01-13
 2012-01-31
 2012-01-16
 2012-01-31
 2012-01-12
 ...

为什么?

我希望在日期间隔1-01-01 ... 31年1月12日。

Answer 1:

您预计1-01-01 ... 1-12-31 ......但PostgreSQL的应该是如何知道你的意思吗?

字符串文本是根据当前的区域设置的解释,特别是lc_time投时timestampdate 。 我引用手册这里 :

LC_TIME(串)

设置要为to_char族函数用于格式化的日期和时间,例如语言环境。 可接受的值为系统依赖型; 见第22.1节以获取更多信息。 如果该变量被设置为空字符串(这是默认值),则该值从服务器的一个系统相关的方式执行环境继承。

在你的情况下,被肢解的时间戳文字1-12-31 23:59:59明显解释为:

D-MM-YY h24:mi:ss

虽然你会希望:

Y-MM-DD h24:mi:ss

3个选项

  1. 设置lc_time为你做,这样的解释文字以同样的方式一个区域。 不知道有一个。

  2. 使用to_timestamp()来解释字符串中明确定义的方式直译-独立于当前的语言环境。 好多了。

     SELECT to_timestamp('1-12-31 23:59:59', 'D-MM-YY h24:mi:ss') 
  3. 更重要的是,使用ISO 8601格式YYYY-MM-DD )的所有日期时间文字。 这是明确的任何区域

     SELECT '2001-12-31 23:59:59'::timestamp 

重写查询

最后,您的查询是错误的开始。 不同的处理范围查询。 重写查询到:

SELECT d.given_on 
FROM   documents_document d
WHERE  EXTRACT('month' FROM d.given_on) = 1
AND    d.given_on >= '2001-01-01 0:0'
AND    d.given_on <  '2002-01-01 0:0'
ORDER  BY d.created_on DESC;

或者更简单的:

SELECT d.given_on 
FROM   documents_document d
WHERE  d.given_on >= '2001-01-01 0:0'
AND    d.given_on <  '2001-02-01 0:0'
ORDER  BY d.created_on DESC;

该新系列类型PostgreSQL 9.2的可能是你的兴趣。



Answer 2:

SELECT '1-12-31 23:59:59.999999'::timestamp; 返回2031-01-12 23:59:59.999999 ,显然Postgres没有考虑年没有世纪中日第一要素。



Answer 3:

你没有说你希望它是什么格式,所以还给原生格式。 也许你甚至认为每个人都表示时间你的方式? 看看可能的格式。 http://www.postgresql.org/docs/8.2/static/functions-formatting.html



文章来源: PostgreSQL: between with datetime