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

Posted

技术标签:

【中文标题】Rails / SQL 查询查找最近的事件【英文标题】:Rails / SQL Query finding most recent Event 【发布时间】:2015-01-22 17:12:37 【问题描述】:

我使用的是 Rails 4.2 和 PostgreSQL 9.4。

我有一个基本的用户、预订和活动架构。

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

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

我的应用程序不允许用户保留具有相同开始时间的两个事件,但是我很欣赏 SQL 对此一无所知,并认为结果中可能有多个事件。因此,在 events.starts_at 的假设“领带”的情况下,我很高兴查询随机返回适当的事件 ID。

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

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

我的基本模型:

Userhas_many :reservations

Reservationbelongs_to :userbelongs_to :event

Eventbelongs_to :companyhas_many :reservations

【问题讨论】:

【参考方案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

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

【讨论】:

【参考方案2】:

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

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

然后加入用户和事件。

假设结果将包括每个用户和事件,那么检索所有用户和事件并存储在两个以 id 为键的数组中可能会更有效。

其背后的逻辑不是由 db 引擎为每个结果预订单独查找用户和事件表,而是在单个查询中获取所有这些更有效。

SELECT * FROM Users' WHERE 1 ORDER BYuser_id`

选择 * FROM Events' WHERE 1 ORDER BYevent_id`

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

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

然后在处理 Reservations 时,您会从数组中获取用户和事件数据。

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

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

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

【讨论】:

以上是关于Rails / SQL 查询查找最近的事件的主要内容,如果未能解决你的问题,请参考以下文章

Access SQL 查询:查找表中每个不同条目的日期最近的行

第30天SQL进阶-查询优化- performance_schema系列实战五:查看最近的事务执行信息(SQL 小虚竹)

优化 Rails 急切加载查询以查找所有

如何在 Rails 中链接原始 SQL 查询或如何从 Rails 中的原始 SQL 查询返回 ActiveRecord_Relation?

如何将sql中的查询转换为rails中的查询

在 Rails 中,如何在一个查找器中查询两个 has_many 关联?