如何从 Arel 中的别名表生成选择?

Jam*_*tby 0 ruby activerecord ruby-on-rails arel

我需要使用带有表单的 Arel 生成 SQL

SELECT c2.user_id, MAX(c2.created_at) as max_created_at
FROM comments AS c2
GROUP BY c2.user_id
Run Code Online (Sandbox Code Playgroud)

在更大的查询中用作子查询

SELECT *
FROM comments
INNER JOIN (...subquery...) s1
ON comments.user_id = s1.user_id
AND comments.created_at = s1.max_created_at
Run Code Online (Sandbox Code Playgroud)

我不知道如何comments在子查询中为表设置别名。

我能得到的最接近的是

c2 = Comment.arel_table.alias
s1 = Comment.arel_table.project(
    c2[:user_id], c2[:created_at].maximum.as('max_created_at')
    ).group('user_id').as('s1')
Run Code Online (Sandbox Code Playgroud)

但这会生成不正确的 SQL

SELECT c2.user_id, MAX(c2.created_at) as max_created_at
FROM comments
GROUP BY c2.user_id
Run Code Online (Sandbox Code Playgroud)

(错误,因为未定义 c2)

生成没有别名的查询会导致不正确的结果,因为子查询内外的表名发生冲突。

这给出了Arel::TableAlias必须project方法的错误。

s1 = c2.project(...
Run Code Online (Sandbox Code Playgroud)

如何使用 Arel 查询别名表?

Sim*_*ime 5

您可以使用from来告诉它从哪个表(或在本例中为表别名)进行投影:

c2 = Comment.arel_table.alias
s1 = Comment.arel_table.
  project(c2[:user_id], c2[:created_at].maximum.as('max_created_at')).
  from(c2).group('user_id').as('s1')
puts s1.to_sql
# (SELECT "comments_2"."user_id", MAX("comments_2"."created_at") AS max_created_at
#  FROM "comments" "comments_2" GROUP BY user_id) s1
Run Code Online (Sandbox Code Playgroud)