Rails / SQL查找查找最近的事件

时间:2015-01-22 17:12:37

标签: sql ruby-on-rails postgresql

我使用的是Rails 4.2和PostgreSQL 9.4。

我有基本用户,预订和事件架构。

我想返回一个用户列表和他们参加的最新活动,以及这个活动的日期/时间。

我创建了一个返回用户和最近事件时间的查询。但是我还需要返回 events.id

我的应用程序不允许用户使用相同的开始时间保留两个事件,但我感谢SQL对此没有任何了解,并认为结果中可能有多个事件。因此,我很高兴查询在假设的'平局的情况下随机返回适当的事件ID。 for events.starts_at。

User.all.joins(reservations: :event) .select('users.*, max(events.starts_at)') .where('reservations.state = ?', "attended") .where('events.company_id = ?', 1) .group('users.id')

相应的SQL查询是: SELECT users.*, max(events.starts_at) FROM "users" INNER JOIN "reservations" ON "reservations"."user_id" = "users"."id" INNER JOIN "events" ON "events"."id" = "reservations"."event_id" WHERE (reservations.state = 'attended') AND (events.company_id = 1) GROUP BY users.id

预留表非常大,因此将整个集合加载到Rails并通过Ruby代码处理它是不可取的。如果可以的话,我想在SQL中执行整个查询。

我的基本模特:

User
has_many :reservations

Reservation
belongs_to :user
belongs_to :event

Event
belongs_to :company
has_many :reservations

2 个答案:

答案 0 :(得分:1)

返回最新事件数据的通用sql如下所示:

select yourfields
from yourtables
join 
(select someField
, max(datetimefield) maxDateTime
from table1
where whatever
group by someField ) temp on table1.someField = temp.somefield
and table1.dateTimeField = maxDateTime
where whatever

两个“凡什么”的东西都应该是一样的。您所要做的就是将此构造调整到您的应用程序中。您可以考虑将查询放入存储过程中,然后从应用程序中调用该存储过程。

答案 1 :(得分:0)

我认为您的查询应首先关注以检索最近的预订。

SELECT MAX(`events.starts_at`),`events"."id`,`user_id` FROM `reservations`  WHERE (reservations.state = 'attended') 

然后加入用户和活动。

假设结果将包括每个用户和事件,检索所有用户和事件可能更有效,然后存储在由id键入的两个数组中。

这背后的逻辑不是单独查找db引擎对每个结果预留的用户和事件表,而是在单个查询中将它们全部都更有效。

SELECT * FROM Users' WHERE 1 ORDER BY user_id`

SELECT * FROM Events' WHERE 1 ORDER BY event_id`

我不熟悉Rails语法,因此不能给出确切的代码,但可以在PHP代码中使用它,结果只用一行代码放入数组。

while ($row = mysql_fetch_array($results, MYSQL_NUM)){users[$row(user_id)] = $row;}

然后在处理预订时,您将从阵列中获取用户和事件数据。

预订索引至关重要,可能值得分析。

可能的个人资料选择可能是包含和排除“有人参与”#39;在索引中。 events.starts_at应该是索引中的第一列,后跟user_id。但应分析对索引列顺序的分析。

您可能希望使用唯一索引来强制执行无重复的预订时间。