Squeel 子查询

Posted

技术标签:

【中文标题】Squeel 子查询【英文标题】:Squeel subquery 【发布时间】:2016-04-11 17:48:21 【问题描述】:

我正在尝试使用子查询来选择某些记录的最新状态。我在 SQL 中有以下查询,我想使用 squeel gem 在 Rails 中重新创建:

SELECT * FROM
changerequests c JOIN
    (SELECT changerequest_id,  max(created_at) max_created_at from 
     changerequest_statuses 
     GROUP BY changerequest_id) as max_status
ON c.id = max_status.changerequest_id
JOIN changerequest_statuses cs
ON cs.changerequest_id = c.id and max_status.max_created_at = cs.created_at
JOIN dim_change_statuses dcs
ON dcs.id = cs.dim_change_status_id

按照此处的指南:https://github.com/activerecord-hackery/squeel#joins 我有以下子查询:

subquery = ChangerequestStatus.group(:changerequest_id).select  [changerequest_id, max(created_at).as(max_date)] 

这行得通。但是将它加入到 Changerequest 模型中,我得到一个 NoMethodError: undefined method 'changerequest_id' for #<Hash> 错误

Changerequest.joins[changerequest_statuses, subquery.as('max_status').on  id == max_status.changerequest_id]

这对我来说看起来像相同的语法。什么给了?

【问题讨论】:

【参考方案1】:

我发现创建这些作用域解决了这个问题:

在 ChangerequestStatus.rb 中:

scope :max_id, -> select('MAX(id) as max_id').group(:changerequest_id).map(&:max_id)

在 Changerequest.rb 中:

scope :max_condition, -> where('changerequest_statuses.id IN (?)', ChangerequestStatus.max_id)

这只是部分解决方案,因为它仅适用于 ID 而不是日期,并假定较晚日期的记录总是具有更高的 ID,但情况并非总是如此。

【讨论】:

以上是关于Squeel 子查询的主要内容,如果未能解决你的问题,请参考以下文章

在 Ruby on Rails 4 中使用 Active Record 或 Squeel Gem 重写 SQL 查询

需要帮助重新编写一些最初使用名为 Squeel 的 gem 编写的 Rails DB 查询,具有有效的 SQL

SQL中的子查询

SQL 子查询

MySQL子查询(六)

SQl子查询