以下等效的rails语句是什么?
@temp = Post.find_by_sql("SELECT posts.id,posts.title, comment_count.count FROM posts INNER JOIN (SELECT post_id, COUNT(*) AS count FROM comments GROUP BY post_id) AS comment_count ON comment_count.post_id = posts.id ORDER BY count DESC LIMIT 5;")
是否可以将其转换为find / where / select语句?
这是一个复杂的查询,我无法得到它,但尝试了类似的东西,
@temp = Post.select("posts.id, posts.title, comment_count.count").joins(:comments).group("post_id").order("countpages.counts desc").limit(5)
答案 0 :(得分:1)
使用像Arel之类的东西可以进一步清理它,我的意思是开始在我的下一个应用程序中使用它(还没有)。
@temp = Post.find_by_sql("SELECT posts.id,posts.title, comment_count.count FROM posts INNER JOIN (SELECT post_id, COUNT(*) AS count FROM comments GROUP BY post_id) AS comment_count ON comment_count.post_id = posts.id ORDER BY count DESC LIMIT 5;")
可能(只是更清洁,但允许你至少链接范围):
@temp = Post.joins("JOIN (SELECT post_id, COUNT(*) AS count FROM comments GROUP BY post_id) AS comment_count ON comment_count.post_id = posts.id").order("count desc").limit(5)
我非常确定Arel
会让您通过范围更优雅地进行子选择,但我不熟悉它以便为您提供解决方案。
修改强>
您可以在counter_cache
模型上的comments
关联中添加Post
,以避免每次都计算它。
class Post < ActiveRecord::Base
has_many :comments, :counter_cache => true
end
来自here的文档
:counter_cache
通过缓存关联类的归属对象数 使用increment_counter和decrement_counter。计数器缓存 在创建和减少此类的对象时递增 当它被摧毁。这需要一个名为的列 #{table_name} _count(例如所属的Comment的comments_count class)用于关联类(例如Post类)。您可以 还可以通过提供列名来指定自定义计数器缓存列 而不是此选项的真/假值(例如:counter_cache =&gt; :my_custom_counter。)注意:指定计数器缓存会将其添加到 该模型使用attr_readonly的只读属性列表。
答案 1 :(得分:1)
你不需要这里的子查询,你可以简单地说:
Post.select("posts.id, posts.title, COUNT(*) count").
joins(:comments).
group('posts.id').
order('count DESC').
limit(5)