我正在 Rails 应用程序中使用 PostgreSQL 数据库,并面临着仅根据用户表中的
timestamp
类型 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:00
和12:30
之间创建的所有用户。
我也尝试过这个:
User.where("EXTRACT(HOUR FROM created_at) BETWEEN ? AND ?", 14, 15)
但它只处理小时而不是分钟。
所需时间可以是
10
-12
小时或 10:00
-12:30
。
如果我想提取从10:00
到12:30
的记录,我该如何管理这些分钟?
简而言之,我正在寻找可以指定所需时间并获取这些时间段内的所有记录的方法。
time
类型,您可以将 timestamp
转换为该类型,以便一次性提取几小时内的所有内容(不排除秒和秒的分数)。 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';
创建于 |
---|
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 |
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
上添加
功能索引来进一步加快速度:
create index on test((created_at::time));