Den*_*SkS 13 sql postgresql datetime postgresql-8.4
我使用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
Run Code Online (Sandbox Code Playgroud)
我得到了结果:
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
...
Run Code Online (Sandbox Code Playgroud)
为什么?
我希望日期在1-01-01 ... 1-12-31.
Erw*_*ter 24
你期待1-01-01 ... 1-12-31......但是PostgreSQL怎么会知道你的意思呢?
字符串文字根据您当前的语言环境设置进行解释,特别是lc_time在转换为timestamp或时date.我在这里引用手册:
lc_time(字符串)
设置用于格式化日期和时间的语言环境,例如使用to_char系列函数.可接受的值取决于系统; 有关更多信息,请参见第22.1节.如果此变量设置为空字符串(这是默认值),则该值将以与系统相关的方式从服务器的执行环境继承.
在您的情况下,残缺的时间戳文字1-12-31 23:59:59显然被解释为:
D-MM-YY h24:mi:ss
Run Code Online (Sandbox Code Playgroud)
虽然你希望:
Y-MM-DD h24:mi:ss
Run Code Online (Sandbox Code Playgroud)
设置lc_time为以与您相同的方式解释此类文字的语言环境.不确定是否有.
用于to_timestamp()以明确定义的方式解释字符串文字 - 独立于当前区域设置.好多了.
SELECT to_timestamp('1-12-31 23:59:59', 'D-MM-YY h24:mi:ss')
Run Code Online (Sandbox Code Playgroud)更好的是,对所有日期时间文字使用ISO 8601格式(YYYY-MM-DD).这与任何语言环境都是明确的.
SELECT '2001-12-31 23:59:59'::timestamp
Run Code Online (Sandbox Code Playgroud)最后,您的查询开始时有问题.以不同方式处理范围查询.将您的查询重写为:
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;
Run Code Online (Sandbox Code Playgroud)
或者,更简单:
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;
Run Code Online (Sandbox Code Playgroud)
您可能会对PostgreSQL 9.2的新范围类型感兴趣.
| 归档时间: |
|
| 查看次数: |
43762 次 |
| 最近记录: |