Rails在小时和分钟之间查询

时间:2012-07-28 23:59:33

标签: ruby-on-rails-3 postgresql activerecord

Rails 3 app,pg adapter,我的架构看起来像:

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代码中的所有日期:(

2 个答案:

答案 0 :(得分:1)

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

以下基本思路是所有时间戳都转换为同一天,因此可以比较小时和分钟:

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

  3. 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
    

答案 1 :(得分: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")