【问题标题】:Rails select subquery (without finder_sql, if possible)Rails 选择子查询(如果可能,不带 finder_sql)
【发布时间】:2014-02-28 16:09:06
【问题描述】:

我有一个名为 Object 的模型(不管它是什么)

它有一个默认价格(列称为“价格”)。

还有一个 Schedule 对象,允许覆盖特定日期的价格。

我希望能够在 SQL 查询期间确定最低价格(根据定义,这是默认价格和“当前”价格之间的最低价格),以便能够按计算出的最低价格进行排序

我想让我的搜索查询尽可能高效,我想知道我是否可以 做这样的事情:

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)

但是,它会生成一个奇怪的 SQL,如下所示:

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 ....)

所以,如您所见,它不起作用。首先 - 它从 objects 表中加载所有列,其次 - 它看起来很糟糕。

我不想使用 finder_sql 的原因是我有很多可选参数和东西,所以在自己获取结果之前使用 AR::Relation 对象是非常可取的。

除了上述之外,我在数据库中有很多记录,我认为将它们全部加载到内存中并不是一个好主意,这就是我想要执行这个子查询的主要原因 - 只是为了过滤- 输出尽可能多的记录。

有人可以帮助我如何更有效地做到这一点吗?

【问题讨论】:

  • 检查你的语法,你的 SQL 中有一些不平衡的括号和反引号。
  • @PinnyM 我只是复制粘贴太快了,很抱歉。

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


【解决方案1】:

如果您单独生成子查询并使用连接而不是相关子查询,则可以使这更容易:

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)

【讨论】:

  • 感谢您的回答。我现在无法检查它,但它可以与其他“连接”一起使用吗?
  • 可以,只要在连接字符串后面加上,逗号分隔
  • 我提到过这样的事情: Object.joins("(#{subquery}) schedules ON objects.p_id = schedules.object_id").joins(:tags).select('objects. *, schedules.min_price).limit(5) 这行得通吗? :)
  • 当然可以。您可以将多个 joins 语句链接在一起,因此应该可以正常工作。
  • 你好。我有机会试用您的代码,但它不起作用。它生成以下 SQL: SELECT objects.*, schedules.min_price FROM objects (SELECT MIN(price) AS min_price, object_id FROM schedules GROUP BY object_id) schedules ON objects.id = schedules.object_id LIMIT 5 你知道怎么做吗要解决这个问题 ? :)
猜你喜欢
  • 1970-01-01
  • 2014-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多