假设我的父评论有很多回复。
class Comment < ActiveRecord::Base
has_many :replies
class Reply < ActiveRecord::Base
belongs_to :topic
我想按created_at
,但订购我的评论,如果他们有更新的回复,我希望家长评论按其最新回复{{1}排序而不是它自己的created_at。
因此,例如,如果我有3条评论,一条为第1天,第2天和第3天发布。第1天是最早的,但第2天有今天发布的回复,我该如何对其进行排序以便结果将是:
created_at
第2天的是最近的活动,比当天早些时候发布的第3天评论更新。
这会是什么方法?
答案 0 :(得分:2)
最好通过您的模型处理日期:
class Comment < ActiveRecord::Base
has_many :replies
end
class Reply < ActiveRecord::Base
belongs_to :comment, touch: true
end
请注意touch: true
关联中的belongs_to: comment
。保存updated_at
Comment
的{{1}}属性
现在只需在选择评论时按Reply
排序。
答案 1 :(得分:2)
最佳查询(如最佳效果)是添加额外的last_activity
列。保持后者(自动,使用触发器或一些RoR内置糖)并在其上添加索引。然后,您将能够使用普通查询获取该列排序的行。
备选方案是与聚合的丑陋连接(请参阅一小时前的答案)。它不会很漂亮,随着你的桌子大小的增长,它会执行非常。
答案 2 :(得分:1)
我想这样的事情可能“好”,但请查看查询计划。 (我自己只处理LINQ和SQL Server - YMMV。)
select * from comments c
left join (select r.comment_id, max(r.created_at) as created_at
from replies r
group by r.comment_id) lr
on lr.comment_id = c.comment_id
order by isnull(lr.created_at, c.created_at) desc
答案 3 :(得分:1)
在LEFT JOIN
到最新响应(可能不存在,因此为LEFT
)后,在ORDER BY
中使用(SQL标准)COALESCE
。但根据您的要求,只有来自SELECT
的{{1}}列:
comments
由于逻辑规定回复必须在评论之后。如果不是这样,那么您可以使用SELECT c.*
FROM comments c
LEFT JOIN (
SELECT comment_id, max(created_at) AS created_at
FROM replies
GROUP BY 1
) r USING (comment_id)
ORDER BY COALESCE(r.created_at, c.created_at) DESC
。