【问题标题】:Rails Activerecord Relation: using subquery as a table for a SQL joinRails Activerecord 关系:使用子查询作为 SQL 连接的表
【发布时间】:2017-09-02 23:50:37
【问题描述】:

谁能帮我弄清楚如何在 Rails 中编写以下 SQL 语句?

SELECT * FROM shifts a
INNER JOIN (
    SELECT shifts.date, shifts.time, max(shifts.barber_id) as 'barber_id'
    FROM shifts 
    WHERE shifts.date = '2017-09-06' and shifts.is_free = true
    GROUP BY shifts.date, shifts.time
) b 
ON a.date = b.date AND a.time = b.time AND a.barber_id = b.barber_id
WHERE a.`is_free` = true AND a.date = '2017-09-06'

因为子查询和主查询中的 where-conditional 相同,所以我使用的范围如下:

scope :available, -> { where('shifts.is_free', true).where('shifts.date', '2017-09-06').order(date: :desc, time: :asc) }

我还创建了子查询的范围:

scope :grouped_shifts, -> { select("date, time, max(barber_id) as barber_id").group(:date, :time).available }

但我不知道如何链接范围以加入方法。我可以将它作为参数传递吗?像这样:

scope :something, -> { joins(self.grouped_shifts).available }

或者在这种情况下我不应该使用作用域? 提前感谢您的帮助!

【问题讨论】:

  • 通过查看您的 SQL,我看不出整个查询的结果与仅内部查询的结果有何不同。
  • 在我的表中,我有几条相同日期和时间的记录,但 barber_id 字段不同。我要做的是过滤表格并在每组日期和时间中只选择 barber_id 最大值的行,因此在该组中将只有一个唯一记录

标签: mysql ruby-on-rails rails-activerecord


【解决方案1】:

将您在问题中所说的话和您对问题的第一条评论拼凑在一起,我认为您正在尝试这样做:

有很多理发师,每个人都有很多班次。每个班次都有一个日期和时间,每个理发师在任何给定班次都可能有空。

您要查找,对于 2017-09-06 的每个时间段,至少有一个可用的理发师,该时间段中可用的理发师具有最大的 id(按时间段排序)

这就是你的做法:

Shift.where(date: '2017-09-06').where(is_free: true).order(:time).group(:time).maximum(:barber_id)

您无需按日期分组,因为所选的所有班次都在同一日期。如果你想将它扩展到表中的所有日期,那么它看起来像这样:

Shift.where(is_free: true).order(:date, :time).group(:date, :time).maximum(:barber_id)

【讨论】:

  • 哦,谢谢!是的,结果是一样的,但是我的查询返回对象集合,而您的代码返回哈希,键为数组 [日期,时间],值等于 barber_id。可能我会写另一种方法来重新格式化它。还是非常感谢。
猜你喜欢
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 2015-09-04
  • 2012-05-10
  • 1970-01-01
  • 2013-04-25
  • 1970-01-01
相关资源
最近更新 更多