【问题标题】:PostgreSQL: between with datetimePostgreSQL:与日期时间之间
【发布时间】:2012-09-07 16:44: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 之间。

【问题讨论】:

    标签: sql postgresql datetime postgresql-8.4


    【解决方案1】:

    你期待1-01-01 ... 1-12-31 ...但是PostgreSQL应该怎么知道你的意思呢?

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

    DateStyle (string)

    设置日期和时间值的显示格式以及规则 用于解释不明确的日期输入值。由于历史原因, 这个变量包含两个独立的组件:输出格式 规范(ISOPostgresSQLGerman)和 年/月/日排序的输入/输出规范 (DMY, MDY, 或YMD)。这些可以单独设置或一起设置。关键词 EuroEuropeanDMY 的同义词;关键字US, NonEuroNonEuropeanMDY 的同义词。有关更多信息,请参阅Section 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)。那是unambiguous and independent from any settings

       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;
    

    Range types 可能对 PostgreSQL 9.2 或更高版本感兴趣。

    【讨论】:

    • 感谢您的回复!我想,我在星期一做第三个选择。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      SELECT '1-12-31 23:59:59.999999'::timestamp; 返回2031-01-12 23:59:59.999999,显然 Postgres 不会将无世纪的年份视为日期中的第一个元素。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-22
        • 2010-12-21
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        • 2019-06-05
        • 1970-01-01
        相关资源
        最近更新 更多