繁体   English   中英

查询忽略时间戳日期的时间范围

[英]Query on a time range ignoring the date of timestamps

我正在尝试在我的 rails 数据库 (Postgres) 中查询采购表,并且我想查询时间范围。

例如,我想知道所有日期在下午 2 点到 3 点之间进行了多少次购买。

此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。

我试过:

Purchases.where("created_at BETWEEN ? and ?", Time.now - 1.hour, Time.now)

但这最终只会用这些时间搜索今天的日期。

您只需要使用PostgreSQL 的 date_part/extract 函数从 created_at 中提取小时部分。

SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 20

例如,这样的事情:

Purchases.where(["EXTRACT(HOUR FROM created_at) BETWEEN ? AND ?", 13, 14])

使用简单的time

Purchases.where("created_at::time >= ?
             AND created_at::time <  ?", Time.now - 1.hour, Time.now)

通过这种方式,您可以轻松地针对任意时间进行测试。

考虑:

  • 要包含/排除的边框。 通常的做法是包括下边界并排除上边界。 BETWEEN包括两者。

  • 确切的数据类型( timestamptimestamp with time zone )以及它如何与您的本地时区交互:

索引

如果您经常运行这些查询并且需要它们快速并且您的表不是很小,您将需要创建一个功能索引以提高性能:

CREATE INDEX tbl_created_at_time_idx ON tbl (cast(created_at AS time));

我使用标准 SQL 语法cast()而不是 Postgres 语法快捷方式:: 这是索引所必需的。

此索引适用于timestamp [without time zone]因为根据索引的要求,转换是IMMUTABLE的。 但出于同样的原因,它不适用于timestamp with time zonetimestamp with time zone 你可以解决这个问题,但你需要准确定义你需要什么。 使用AT TIME ZONE构造定义要提取时间的时区。 例如,要测量 UTC 时间:

CREATE INDEX tbl_created_at_time_idx2
ON tbl(cast(created_at AT TIME ZONE 'UTC' AS time));

处理忽略年份的日期的类似问题:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM