【问题标题】:Convert SQL to Rails Query将 SQL 转换为 Rails 查询
【发布时间】:2021-05-03 00:25:19
【问题描述】:

我正在尝试将以下 SQL 查询转换为 Rails 可以理解的内容:

SELECT posts.* FROM 
(
SELECT group_id, MAX(updated_at) AS updated_at FROM posts WHERE group_id IN (4, 6, 9) GROUP BY group_id
) AS latest_posts 
INNER JOIN posts ON 
latest_posts.group_id = posts.group_id AND 
latest_posts.updated_at = posts.updated_at;

模型的名称是Post。我的尝试:

Post.select("(SELECT group_id, MAX(updated_at) AS updated_at FROM posts WHERE group_id IN (4, 6, 9) GROUP BY group_id) AS latest_posts")
.joins('INNER JOIN posts ON latest_posts.group_id = posts.group_id AND latest_posts.updated_at = posts.updated_at')

错误:

Error:
UserTest#test_feed_should_have_the_right_posts:
ActiveRecord::StatementInvalid: PG::DuplicateAlias: ERROR:  table name "posts" specified more than once

    test/models/user_test.rb:100:in `block in <class:UserTest>'

更新:关闭但没有雪茄。令人沮丧。

irb(main):046:0> Post.select("posts.* FROM (SELECT group_id, MAX(updated_at) AS updated_at FROM posts WHERE group_id IN (4, 6, 9) GROUP BY group_id) AS latest_posts").joins("INNER J
OIN posts  ON  latest_posts.group_id = posts.group_id  AND  latest_posts.updated_at = posts.updated_at")

生产:

SELECT posts.* FROM 
(SELECT group_id, MAX(updated_at) AS updated_at FROM posts WHERE group_id IN (4, 6, 9) GROUP BY group_id)
 AS latest_posts 
FROM "posts" 
INNER JOIN posts  
ON  latest_posts.group_id = posts.group_id  AND  latest_posts.updated_at = posts.updated_at

【问题讨论】:

  • 你可以在链的末尾调用.to_sql,然后比较SQL
  • 也许如果你给使用的“posts”表的两个不同实例起别名(即“SELECT”语句中的第一个实例和“INNER JOIN”中的第二个实例,那么它可能会按照您的预期工作。我将作为答案发布,所以您明白我的意思 - 尽管我不是 100% 确定

标签: sql ruby-on-rails


【解决方案1】:

试试

Post.select("(SELECT group_id, MAX(updated_at) AS updated_at FROM posts p1 WHERE group_id IN (4, 6, 9) GROUP BY group_id) AS latest_posts")
.joins('INNER JOIN posts p2 ON latest_posts.group_id = p2.group_id AND latest_posts.updated_at = p2.updated_at')

我怀疑通过对“posts”表的两个单独引用进行别名,那么查询将被 Rails 接受

【讨论】:

  • 我不确定你的意思 - 你有没有尝试我的实际建议?您添加到问题中的更新以略微不同的方式构建查询,但这不是我的建议
  • 是的,我试过了,这是错误:Error: UserTest#test_feed_should_have_the_right_posts: ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "latest_posts" LINE 1: ...LECT 1 AS one FROM "posts" INNER JOIN posts p2 ON latest_pos... ^ test/models/user_test.rb:100:in block in `
  • 看起来您在该示例中运行的查询的语法与原始查询的语法不同 - 您是否更改了它?很难尝试解释表名的别名是否是一个问题,或者您引入了导致错误的新语法问题。您尝试执行的导致该错误的完整查询是什么?
  • Post.select("(SELECT group_id, MAX(updated_at) AS updated_at FROM posts p1 WHERE group_id IN (4, 6, 9) GROUP BY group_id) AS latest_posts").joins('INNER JOIN posts p2 ON latest_posts.group_id = p2.group_id AND latest_posts.updated_at = p2.updated_at')
  • 嗨 - 不,我的意思是它显示了您正在运行的查询的一部分...LECT 1 AS one FROM "posts" .....这不是我的答案中的查询。我想看看你现在正在运行的完整查询是什么,这导致了错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多