【问题标题】:Rails relation ordering?Rails 关系排序?
【发布时间】:2021-10-22 15:36:46
【问题描述】:

所以我想把这个 SQL 查询翻译成 Rails(并且按照这个确切的顺序): 假设我有

WITH sub_table as (
  SELECT * FROM main_table LIMIT 10 OFFSET 100 ORDER BY id
)

SELECT * FROM sub_table INNER JOIN other_table
ON sub_table.id = other_table.other_id

这里的重点是执行顺序必须是:

  1. 必须首先执行 sub_table 查询中的 LIMIT 和 OFFSET
  2. 第二个语句应该发生在之后。

所以如果我的关系被称为 OtherTableMainTable 做这样的工作:

subTableRelation = MainTable.order(id: :asc).limit(10).offset(100)
subTableRelation.join(OtherTable, ....)

这里的主要问题是 Rails 关系执行顺序如何影响事物。

【问题讨论】:

  • 您还可以考虑select_all,它可以让您充分利用SQL。

标签: ruby-on-rails arel


【解决方案1】:

虽然 ActiveRecord 在其高级 API 中不提供 CTE,但 Arel 将允许您构建这个精确的查询。

由于您没有提供模型并且混淆了表名,我暂时将在 Arel 中完全构建它。

sub_table = Arel::Table.new('sub_table')
main_table = Arel::Table.new('main_table')
other_table = Arel::Table.new('other_table')

sub_table_query = main_table.project(Arel.star).take(10).skip(100).order(main_table[:id])

sub_table_alias = Arel::Nodes::As.new(Arel.sql(sub_table.name),sub_table_query)

query = sub_table.project(Arel.star)
  .join(other_table).on(sub_table[:id].eq(other_table[:other_id]))
  .with(sub_table_alias)

query.to_sql

输出:

WITH sub_table AS (
  SELECT 
   * 
  FROM main_table 
  ORDER BY main_table.id
  -- Output here will differ by database
  LIMIT 10 OFFSET 100 
)

SELECT 
  * 
FROM sub_table 
INNER JOIN other_table ON sub_table.id = other_table.other_id

如果您能够提供更好的上下文,我可以提供更好的解决方案,很可能会生成一个 ActiveRecord::Relation 对象,该对象可能更适合用于链接和模型访问目的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多