Rails select subquery (without finder_sql, if possible)

廉价感情. 提交于 2020-01-09 11:29:12

问题


I have an model called Object (doesn't really matter what it is)

It has a default price (column is called "price").

And then there is a Schedule object that allows to override the price for specific dates.

I want to be able to determine the MINIMUM price (which is by definition the MINIMUM between the default and "current" price) during the SQL-query just in order to be able to ORDER BY the calculated minimum price

I want to make my search query as efficient as possible and I was wondering if I can do something like that:

Object.select("id AS p_id, id, (SELECT MIN(`schedules`.`price`) FROM `schedules` WHERE `schedules`.`object_id` = p_id`) AS objects.min_price").limit(5)

But, it generates an odd SQL that looks like this:

SELECT `objects`.`id` AS t0_r0, `objects`.`title` AS t0_r1, `objects`.`created_at` AS t0_r2, `objects`.`updated_at` AS t0_r3, `objects`.`preferences` AS t0_r4 ........ (a lot of columns here) ... ` WHERE `objects`.`id` IN (1, 2, 3, 4 ....)

So, as you can see it doesn't work. First of all - it loads all the columns from the objects table, and second of all - it looks horrible.

The reason why I don't want to use finder_sql is that I have a lot of optional parameters and stuff, so using the AR::Relation object is highly preferred prior to fetching the results themselves.

In addition to abovementioned, I have a lot of records in the DB, and I think that loading them all into the memory is not a good idea and that is the main reason why I want to perform this subquery - just to filter-out as many records as possible.

Can someone help me how to do it more efficiently ?


回答1:


You can make this easier if you generate the subquery separately and use a join instead of a correlated subquery:

subquery = Schedule.select('MIN(price) as min_price, object_id')
                   .group(:object_id)
                   .to_sql
Object.joins("JOIN (#{subquery}) schedules ON objects.p_id = schedules.object_id")
      .select('objects.*, schedules.min_price')
      .limit(5)


来源:https://stackoverflow.com/questions/21556733/rails-select-subquery-without-finder-sql-if-possible

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!