【问题标题】:Select a date range from a timestamp column从时间戳列中选择日期范围
【发布时间】:2011-11-16 20:55:40
【问题描述】:

目前我的表有一个列来存储日期和时间。该列的数据类型是timestamp without time zone。所以它的值格式为'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'

它将提供介于“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'

没有日期、月份和秒,它不显示任何行。

如何从该表中获取关于日期的值(仅带日期,忽略小时、分钟和秒)?

即使该列有带时间戳的日期,我只需要使用日期搜索它们(忽略时间戳或将小时、分钟和秒设为0,例如'2011-09-13 00:00:00.0')。

【问题讨论】:

    标签: sql postgresql timestamp date-range


    【解决方案1】:

    如果您要将字段的timestamp 值转换为date,正如另一个答案中所建议的那样,性能会降低,因为需要转换列中的每个值以进行比较并且不能使用简单的索引.您必须创建一个特殊的index on the expression,如下所示:

    CREATE INDEX some_idx ON tbl (cast(mdate AS date));
    

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

    SELECT * FROM tbl
    WHERE  mdate::date = '2011-09-12'::date; -- 2nd cast optional
    

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

    SELECT * FROM tbl
    WHERE  mdate >= '2011-09-12 00:00:00.0'
    AND    mdate <= '2011-09-13 00:00:00.0';

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

    SELECT * FROM tbl
    WHERE  mdate >= '2011-09-12 00:00'
    AND    mdate <  '2011-09-13 00:00';
    
    • 无需拼出秒数和 0 分数。
    • 您不想包含2011-09-13 00:00,因此请使用&lt; 而不是&lt;=
      出于同样的原因,请勿在此处使用BETWEEN
    <strike>WHERE mdate BETWEEN '2011-09-12 00:00' AND '2011-09-13 00:00'</strike>

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

    另外请注意,timestamp [without time zone] 类型的列会根据您当前的时区设置进行解释。日期部分取决于该设置,该设置通常应按预期工作。更多详情:

    【讨论】:

      【解决方案2】:

      只需将时间戳视为日期:

      select * 
      from table 
      where mdate::date >= DATE '2011-09-12' 
        and mdate::date <= DATE '2011-09-13'
      

      表达式mdate::date 会将时间戳转换为date 类型,这将从值中删除时间部分。

      DATE '2011-09-13' 是一个(标准)DATE 文字,它比简单地写 '2011-09-13' 更健壮,因为它不受任何语言设置的影响。

      【讨论】:

      • mdate::dateDATE mdate 是同义词。 '2011-09-13'::datedate '2011-09-13' 是同义词。只是语法风格不同。你让它看起来好像有区别。
      • @Erwin:'2011-09-13' 不依赖系统设置吗?这样它就可以在一个安装上工作,但不能在另一个安装上工作?
      • 这个问题与我关于强制转换语法的陈述是正交的。除此之外,日期的“yyyy-mm-dd”对于任何语言环境都是明确的。 http://www.postgresql.org/docs/9.0/interactive/datatype-datetime.html
      • @Erwin:感谢您澄清这一点(你生活和学习......)我认为它受到了 DateStyle 配置设置的影响:postgresql.org/docs/current/static/…
      • @a_horse_with_no_name:日期/时间数据的输入格式中的一些细节DateStyle设置的影响,你离那里不远了。但不是强制转换语法,也不是 ISO 8601 格式“yyyy-mm-dd”,即unambiguous in any mode
      猜你喜欢
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      • 1970-01-01
      • 2013-01-10
      • 2018-03-03
      • 1970-01-01
      相关资源
      最近更新 更多