查找所有值小于具有关联活动记录的两列之和的所有记录

时间:2021-05-25 21:54:38

标签: ruby-on-rails ruby ruby-on-rails-6

我有一个 Room 模型,它与 ReservationRoom 相关联。 (room => has_many :reservations_rooms)

现在我想找到符合以下条件的房间

ReservationRooms 有两列名为 number_of_adultsnumber_of_child

房间有名为 min_occupancy

的列

我需要所有房间记录

如果reservation_rooms number_of_adults 和number_of_child 之和,则小于min_occupancy 房间表。

下面的链接。

Room.joins(:reservations_rooms).where(id: [22, 19]).having('sum(reservations_rooms.number_of_adult + reservations_rooms.number_of_child) < rooms.min_occupancy')

有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

试试这个,我觉得你不需要分组

Room.joins(:reservation_rooms).
  where(rooms: { id: [22, 19] }).
  where('reservation_rooms.number_of_adults + reservation_rooms.number_of_child <= rooms.min_occupancy')

我留下了关于 ids 的条件,因为我不知道你是否也需要它

答案 1 :(得分:1)

您要查找的是 where 子句。您可以在 ActiveRecord 中组合多个 where 并且将与 AND 组合:

Room                             # the model you are interested in
  .joins(:reservation_rooms)     # combine the reservations
  .where(rooms: {id: [22, 19]})  # only for those two rooms
  .where(
    "number_of_adults + number_of_child <= min_occupancy"
  )                              # add adults/child and compare to occupancy

这应该生成与此类似的 SQL。

select * from rooms
joins reservation_rooms on roomws.id = reservation_rooms.room_id
where 
  rooms.id in (22, 19)
  and number_of_adults + number_of_child <= max_occupancy

一些注意事项:

  • 您可以通过将 .to_sql 附加到您的 ActiveRecord::Association(您构建的查询)来查看生成的 SQL
  • 假设列名是唯一的,您不需要在它们前面加上表名(例如,如果机器人表有一个 created_at 列,您需要指定您感兴趣的列,例如 {{1} }).
  • 我会将 rooms.id 重命名为 number_of_child 以保持一致(number_of_children 上是复数)
  • number_of_adults 是一个聚合函数(如 sumavg 等)。这些函数用于将多列组合 为一。 (在您的示例中,您希望合并一行的多列,因此您可以使用 count
  • + 也与 group 一起使用。它类似于 having 子句,但用于过滤 whereed 行