我在Rails应用程序中使用一个PostgreSQL数据库,在仅根据USERS表的timestamp TYPE created_at列中的时间部分提取用户记录方面面临挑战.

此查询运行良好:

users = User.where("    DATE_PART('hour',   created_at) >= ? 
                    AND DATE_PART('minute', created_at) >= ? 
                    OR  DATE_PART('hour',   created_at) <= ? 
                    AND DATE_PART('minute', created_at) <= ?", 
                    10, 0, 15, 30).pluck :created_at

但我很好奇是否有更好的方法来提取所需的记录.从本质上讲,我的目标是仅根据时间查询记录,不包括日期.例如,我希望检索在任何一天(年、月和日)创建的10:0012:30之间的所有用户.

我还try 了这个:

User.where("EXTRACT(HOUR FROM created_at) BETWEEN ? AND ?", 14, 15)

但它只处理小时,而不是分钟.

所需时间可以是10-12小时或10:00-12:30小时. 如果我想提取从10:0012:30的记录,我如何管理这几分钟?

简而言之,我正在寻找一种方法,在这种方法中,我可以指定所需的时间并获得这些时间段内的所有记录.

推荐答案

PostgreSQL有一个time类型,您可以将其强制转换为timestamp,以便一次性提取从几个小时到几个小时的所有内容(不包括秒和秒的分数).Demo at db<>fiddle:

create table test(created_at timestamp);

--sample timestamps around every hour between now and 4 days from now
insert into test select g+random()*'1h'::interval 
from generate_series(now(),now()+'4 days','1h')_(g);
select created_at
from test
where created_at::time between '11:15' and '12:21:10.123';
created_at
2023-12-08 11:55:58.167576
2023-12-09 11:39:04.189425
2023-12-10 12:09:11.234004
2023-12-11 11:40:42.80833

从RoR中,您可以将时间字段传递到PostgreSQL make_time()中.第三个字段是double precision,它允许您用分数来表示秒:

User.where("created_at::time BETWEEN make_time(?,?,?) 
                             AND     make_time(?,?,?)", 
           11, 15, 0, 
           12, 21, 10.123)

您还可以传递带有匹配时间的任何时间戳,并强制转换为仅使用其time元素:

User.where("created_at::time BETWEEN cast(:start_time as time) 
                             AND     cast(:end_time   as time)", 
           {start_time: Time.new(2023,12,07,11,15), 
            end_time: DateTime.new(1981,05,05,15,30)} )

可以通过在created_at上添加functional index来进一步加快速度:

create index on test((created_at::time));

Sql相关问答推荐

SQL Google Sheets:UNIQUE/DISTINCT和编码查询函数

使用交叉应用透视表在SQL中转换分段时间段&

对于表A中的每一行,更新表B中与金额有关的行

通过 Select 值的顺序进行排序ClickHouse

在多个联合中使用相同的SELECT SQL查询

snowflake/SQL嵌套的JSON对象和数组

将日期时间转换为日期格式

同一表的Oracle SQL更新(含YTD合计)

TSQL如何为群分配号码

将时间范围划分为全天和前后剩余小时

返回给定日期后的第 4 个工作日(不包括公众假期)

在 PostgreSQL 中,如何让多个判断约束引用相同的值数组?

Clickhouse:左连接表到外部数组

如何获取每个组中最近的n条记录并将它们聚合成数组

强制 SQL 始终通过 R 从视图中返回至少一行

如何获得上个月和下个月之间的销售额差异

在 PostgreSQL 中使用重音敏感排序进行重音不敏感搜索

BigQuery - 将 TIMESTAMP 转换为 HH:MM:SS,然后识别 TIME_DIFF

如何在 Trino/Presto 中过滤掉 map 中的某些键?

SQL 中的问题与包含最大日期的记录连接