18

我使用 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 ... 1-12-31。

4

3 回答 3

34

您期望1-01-01 ... 1-12-31...但是 PostgreSQL 应该如何知道您的意思?

输入字符串文字根据您当前会话的设置进行解释(postgressql.conf除非被否决,否则默认为常规设置)。特别是datestyle

DateStyle( string)

设置日期和时间值的显示格式,以及解释模糊日期输入值的规则。由于历史原因,此变量包含两个独立的组件:输出格式规范(ISOPostgresSQLGerman)和年/月/日排序的输入/输出规范(DMYMDYYMD)。这些可以单独设置或一起设置。关键字 EuroEuropeanDMY;的同义词 关键字US, NonEuroNonEuropean是 的同义词MDY。有关详细信息,请参阅第 8.5 节。内置默认值为ISO, MDY,但 initdb 将使用与所选行为相对应的设置初始化配置文件lc_time语言环境。

(虽然输出格式主要由lc_time.)

在您的情况下,残缺的时间戳文字1-12-31 23:59:59显然被解释为:

D-MM-YY h24:mi:ss

虽然您希望:

Y-MM-DD h24:mi:ss

3个选项

  1. 设置datestyle以便它以与您相同的方式解释文字。也许ISO, YMD

  2. 用于to_timestamp()以明确定义的方式解释字符串文字 - 独立于其他设置。好多了。

     SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD 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 或更新版本中的范围类型可能很有趣。

于 2012-09-14T14:44:48.010 回答
2

SELECT '1-12-31 23:59:59.999999'::timestamp;return 2031-01-12 23:59:59.999999,显然 Postgres 不认为 year-without-century 作为日期中的第一个元素。

于 2012-09-14T13:48:49.187 回答
1

你没有说你想要什么格式。所以它返回了本机格式。也许你甚至认为每个人都像你一样表示时间?看看可能的格式。http://www.postgresql.org/docs/8.2/static/functions-formatting.html

于 2012-09-14T13:52:40.653 回答