1

Rails 3 应用程序,pg 适配器,我的架构如下所示:

create_table "events", :force => true do |t|
 t.integer  "event_type_id"
 t.datetime "start_at"
 #...
end

一些示例数据包括:

p.events.each{|e| puts e.start_at }; 1
2009-03-23 08:30:00 UTC
2009-05-20 07:45:00 UTC
2009-05-20 07:45:00 UTC
2009-03-23 16:00:00 UTC
2009-05-20 10:00:00 UTC
2009-03-23 19:30:00 UTC
2009-03-23 11:30:00 UTC
2009-05-20 07:45:00 UTC
2009-05-20 07:45:00 UTC
2009-05-20 09:00:00 UTC
2009-05-20 07:45:00 UTC

我想在接下来的 3 个小时之间进行搜索,但忽略了这一天!小时和分钟对我来说很重要..
可以在 Postgres 中完成吗?我一直在尝试使用pg EXTRACT(),但到目前为止没有成功

我不想过滤 ruby​​ 代码中的所有日期:(

4

2 回答 2

1

我只介绍一种如何在 PostgreSQL 中完成此操作的方法。我没有 RoR 经验,所以在这方面我无法为您提供帮助。

下面的基本思想是将所有时间戳转换为同一天,以便可以比较小时和分钟:

  1. 将时间戳转换为仅包含几小时一分钟的字符串
  2. 将该字符串转换回时间戳会导致日期部分为第 1 年的 1 月 1 日

create table test (id serial, start_at timestamp);

insert into test(start_at)
select * from generate_series('2008-03-01 00:00'::timestamp,
                              '2008-03-15 12:00', '5 hours');

with 
hh24mi_now as (select to_timestamp(to_char(current_timestamp, 'HH24:MI'), 'HH24:MI'))
select * from test where id in (
  select id
    from test
   where to_timestamp(to_char(start_at, 'HH24:MI'), 'HH24:MI') >= (select * from hh24mi_now)
     and to_timestamp(to_char(start_at, 'HH24:MI'), 'HH24:MI') < (select * from hh24mi_now) + interval '3 hours'
  )
order by id
;

示例运行的结果:

 id |      start_at       
----+---------------------
 13 | 2008-03-03 12:00:00
 18 | 2008-03-04 13:00:00
 23 | 2008-03-05 14:00:00
 37 | 2008-03-08 12:00:00
 42 | 2008-03-09 13:00:00
 47 | 2008-03-10 14:00:00
 61 | 2008-03-13 12:00:00
 66 | 2008-03-14 13:00:00
于 2012-07-29T09:01:59.183 回答
1

忽略分钟,只考虑小时:

#On my model    
scope :next_3_hours, ->(h){
  where( [" date_part( 'hour', \"start_at\") = ? OR date_part( 'hour', \"start_at\") = ? OR date_part( 'hour', \"start_at\") = ? ",h,h+1,h+2])
    .order("date_part( 'hour', \"start_at\") ASC, date_part( 'minute', \"start_at\")")
}

结果:

# on SQL (considering now to be 17:00)
SELECT "events".* FROM "events"
WHERE ( date_part( 'hour', "start_at") = 17 
        OR date_part( 'hour', "start_at") = 18
        OR date_part( 'hour', "start_at") = 19 )
ORDER BY date_part( 'hour', "start_at") ASC, date_part( 'minute', "start_at")
于 2012-08-04T01:38:57.640 回答