Group_by - Ruby / Rails + Postgres

时间:2016-09-30 16:53:46

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

我对ROR和Postgre很陌生,而且我很难实现这一目标。

我有一个Working_hour模型和商家模型,其中商家has_many working_hours和working_hour属于Merchant。商家可以在同一天工作两小时或多小时。

我的观点:

source /home/vagrant/regression_venv/bin/activate

当我在按日排序的视图中显示检索到的数据时(注意开放时间是无序的):

 <% @merchant.working_hours.order(:day).group_by(&:day).each do |dia, whs| %>
   <%= t(:"date.abbr_day_names")[dia.to_i] %> : 
     <% whs.each do |wh| %>
       <li>
         <%= wh.oppening_hour.to_formatted_s(:time)  %> -
         <%= wh.close_hour.to_formatted_s(:time)  %>
       </li>
     <% end %>
  <% end %>

我希望按星期几进行分组,然后先按星期几排序,然后按开放时间排序:

Mon: 
17:00-20:00
10:00-13:00
Tue:
18:00-21:00 
10:00-13:00

但正如您所看到的,目前,我正在使用ruby层来实现性能问题。如何使用数据库层实现这一目标?

4 个答案:

答案 0 :(得分:2)

快速Postgres示例,如果您愿意将数据存储在数据库表中(在随机创建的数据集上):

-- The query:
SELECT      to_char( mytime, 'day' ) as weekday,                -- example to get weekday name
            extract( dow from mytime ) as weekday_num,          -- example to get weekday number
            format(                                             -- format the way example output was given
                '%s - %s',
                date_trunc( 'hour', opening_time )::time(0),    -- get opening hour (without milliseconds)
                date_trunc( 'hour', closing_time )::time(0)     -- get closing hour (without milliseconds)
            ) as working_hours
FROM        mytable
GROUP BY    mytime,         -- to secure accurate ordering by timestamp
            weekday,        
            working_hours
ORDER BY    mytime,
            working_hours;

-- Result:
  weekday  | weekday_num |    working_hours
-----------+-------------+---------------------
 monday    |           1 | 08:00:00 - 17:00:00
 tuesday   |           2 | 08:00:00 - 16:00:00
 tuesday   |           2 | 08:00:00 - 17:00:00
 wednesday |           3 | 08:00:00 - 12:00:00
 thursday  |           4 | 08:00:00 - 12:00:00
 thursday  |           4 | 08:00:00 - 16:00:00
 friday    |           5 | 08:00:00 - 15:00:00
 friday    |           5 | 08:00:00 - 18:00:00

Postgres文档链接可能会派上用场:

https://www.postgresql.org/docs/current/static/functions-datetime.html https://www.postgresql.org/docs/current/static/functions-formatting.html https://www.postgresql.org/docs/current/static/functions-string.html#FUNCTIONS-STRING-FORMAT

P.S。希望能提供一些如何在数据库中解决它的想法。

答案 1 :(得分:2)

工作时间应按opens_hour排序,因为您将按升序显示UI中的开放时间。订购工作时间后,结果可按日分组。

<% @merchant.working_hours.order(:opening_hour).group_by(&:day).each do |dia, whs| %> <%= t(:"date.abbr_day_names")[dia.to_i] %> : <% whs.each do |wh| %> <li> <%= wh.opening_hour.to_formatted_s(:time) %> - <%= wh.close_hour.to_formatted_s(:time) %> </li> <% end %> <% end %>

答案 2 :(得分:2)

<% day = nil %>
<% @merchant.working_hours.order(:day, :oppening_hour).each do |wh| %>
  <% if wh.day != day %>
    <% day = wh.day %>
    <%= t(:"date.abbr_day_names")[day.to_i] %> :
  <% end %>
  <li>
    <%= wh.oppening_hour.to_formatted_s(:time)  %> -
    <%= wh.close_hour.to_formatted_s(:time)  %>
  </li>
<% end %>

答案 3 :(得分:0)

为什么你不能按两个字段排序:&#34; day&#34;并且通过&#34; opening_hour&#34;?

<% @merchant.working_hours.order(:day).order(:oppening_hour).group_by(&:day).each do |dia, whs| %>
   <%= t(:"date.abbr_day_names")[dia.to_i] %> : 
     <% whs.each do |wh| %>
       <li>
         <%= wh.oppening_hour.to_formatted_s(:time)  %> -
         <%= wh.close_hour.to_formatted_s(:time)  %>
       </li>
     <% end %>
  <% end %>