日期范围之间的 Postgresql 查询

Posted

技术标签:

【中文标题】日期范围之间的 Postgresql 查询【英文标题】:Postgresql query between date ranges 【发布时间】:2014-06-13 16:44:15 【问题描述】:

我正在尝试查询我的 postgresql 数据库以返回日期在特定月份和年份的结果。换句话说,我想要一个月的所有值。

到目前为止,我能够做到的唯一方法是这样的:

SELECT user_id 
FROM user_logs 
WHERE login_date BETWEEN '2014-02-01' AND '2014-02-28'

问题是我必须在查询表之前计算第一个日期和最后一个日期。有没有更简单的方法来做到这一点?

谢谢

【问题讨论】:

间隔是否总是一个月,或者可能是,您可能从 15 日开始,到下个月的 7 日结束? 【参考方案1】:

如果你使用>= start AND < end,很多事情都会变得更简单。

例如:

SELECT
  user_id
FROM
  user_logs
WHERE
      login_date >= '2014-02-01'
  AND login_date <  '2014-03-01'

在这种情况下,您仍然需要计算所需月份的开始日期,但这应该以多种方式直接进行。

结束日期也被简化了;只需添加一个月。 28 日、30 日、31 日等不要乱搞。

这种结构还具有能够保持索引使用的优点。

许多人可能会建议如下形式,但他们使用索引:

WHERE
      DATEPART('year',  login_date) = 2014
  AND DATEPART('month', login_date) = 2

这涉及计算表中每一行的条件(扫描),而不是使用索引来查找将匹配的行范围(范围搜索)。

【讨论】:

第一种方法需要花费几个月(而不是几天)f.ex。 2014-12-01 & 2015-01-01。第二个也可以被索引,但这不是微不足道的,我承认——EXTRACT() 似乎更兼容。 您可以通过使用间隔来避免应用程序中的日期计算。例如: WHERE login_date >= '2014-02-01' AND login_date @MatBailie,特别感谢 DATEPART 通知! 完美答案!【参考方案2】:

阅读文档。

http://www.postgresql.org/docs/9.1/static/functions-datetime.html

我使用了这样的查询:

WHERE
(
    date_trunc('day',table1.date_eval) = '2015-02-09'
)

WHERE(date_trunc('day',table1.date_eval) >='2015-02-09'AND date_trunc('day',table1.date_eval) <'2015-02-09')    

华尼托斯·工程师。

【讨论】:

这并不能准确回答问题。该问题要求基于月份和年份的日期。 可能这不能回答问题,但它解决了我的问题。虽然,我有一个问题,如果结束日期是另一个月份,那么返回的数据将来自同一个月还是另一个月份?【参考方案3】:

从 PostreSQL 9.2 开始支持 Range Types。所以你可以这样写:

SELECT user_id
FROM user_logs
WHERE '[2014-02-01, 2014-03-01]'::daterange @> login_date

这应该比字符串比较更有效

【讨论】:

对于登录日期的时间戳类型的任何人:从 user_logs WHERE '[2014-02-01, 2014-03-01]'::daterange @> login_date::date 中选择 user_id 是否可以建立动态范围?我想做一个 INNER JOIN 检查表中的时间戳是否在第二个表上的两个属性的范围内。 看来 tsrange(lower-bound, upper-bound) 可以解决问题! 非常有用,而且非常有用,尤其是当您想要创建像 [from, to)(from, to] 这样的范围时,请确保左侧或右侧与 equal 大小写不匹配跨度> 【参考方案4】:

以防万一有人降落在这里...从 8.1 开始,您可以简单地使用:

SELECT user_id 
FROM user_logs 
WHERE login_date BETWEEN SYMMETRIC '2014-02-01' AND '2014-02-28'

来自文档:

BETWEEN SYMMETRIC 与 BETWEEN 相同,只是没有 要求 AND 左边的参数小于或等于 到右边的论点。如果不是,这两个论点是 自动交换,因此始终隐含一个非空范围。

【讨论】:

请注意,此查询包括2014-02-28 00:00:00【参考方案5】:
SELECT user_id 
FROM user_logs 
WHERE login_date BETWEEN '2014-02-01' AND '2014-03-01'

Between 关键字对某个日期特别有效。它假定日期的时间是 00:00:00(即午夜)。

【讨论】:

请注意,此查询包含2014-03-01 00:00:00

以上是关于日期范围之间的 Postgresql 查询的主要内容,如果未能解决你的问题,请参考以下文章

Postgresql 查询以展开每个客户的开始日期和结束日期之间的所有日期

如何在 PostgreSQL 中合并两个查询?

3个日期范围之间的Mysql查询

在 PostgreSQL 中生成两个日期之间的时间序列

这些查询 MySQL 日期范围之间有啥区别

查询按日期范围分隔的行数