Ruby on Rails+PostgreSQL:查询各客户最新笔记并排序展示
解决方案
针对你的需求——获取每个客户的最新非account_note笔记,并按从旧到新排序,以下是两种适配PostgreSQL的高效实现方式:
方法1:使用DISTINCT ON(PostgreSQL专属语法)
PostgreSQL的DISTINCT ON可以直接返回指定分组的第一条记录,搭配排序规则就能精准拿到每个客户的最新笔记:
@latest_notes_per_customer = Note.where(account_note: false) .select('DISTINCT ON (customer_id) *') .order('customer_id, created_at DESC') .order(created_at: :asc)
DISTINCT ON (customer_id):确保每个customer_id仅返回一条记录order('customer_id, created_at DESC'):指定每个客户分组内按created_at倒序,分组第一条即为该客户的最新笔记- 最后的
order(created_at: :asc):将筛选出的所有最新笔记,整体按创建时间从旧到新排列
方法2:使用窗口函数ROW_NUMBER()
如果需要更灵活的分组筛选逻辑,可以用窗口函数标记每条笔记在所属客户组内的顺序,再筛选出最新条目:
@latest_notes_per_customer = Note.from( Note.select( 'notes.*', 'ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY created_at DESC) AS rn' ).where(account_note: false), :notes ).where(rn: 1).order(created_at: :asc)
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY created_at DESC):按customer_id分组,每组内按created_at倒序给笔记编号,最新笔记的编号为1- 外层查询筛选
rn = 1的记录,即每个客户的最新笔记,最后按创建时间升序排列结果
补充说明
- 无符合条件笔记的客户不会出现在结果集中
- 若同一客户存在多条创建时间完全相同的笔记,
DISTINCT ON会返回其中一条(遵循数据库默认排序),如需明确规则,可在排序时追加id DESC(例如order('customer_id, created_at DESC, id DESC'))
内容的提问来源于stack exchange,提问作者Jrinard
相关产品推荐
相关产品推荐

