You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails带条件Distinct查询:按created_at取各status_type最新记录

注意:示例数据中created_at存在非法日期格式笔误,以下方案默认表中created_at为标准datetime/timestamp类型,可正常进行时间大小比较、排序操作。

以下是不同场景下可用的Rails查询写法,最终都会返回status_type为test、integer的2条最新记录:

PostgreSQL 环境(Rails 最常用搭配)

使用PG原生的DISTINCT ON语法实现,性能最优,写法最简洁:

# 将YourModel替换为实际对应的模型名即可
result = YourModel
  .select("DISTINCT ON (status_type) *")
  .where(status_type: ["test", "integer"])
  .order("status_type, created_at DESC")
MySQL 8.0+ / 支持窗口函数的数据库环境

通过ROW_NUMBER()窗口函数按status_type分组、组内按创建时间倒序排序,取每组第一条:

result = YourModel
  .from(
    YourModel
      .select("*, ROW_NUMBER() OVER (PARTITION BY status_type ORDER BY created_at DESC) AS row_num")
      .where(status_type: ["test", "integer"]),
    :grouped_records
  )
  .where("grouped_records.row_num = 1")
低版本MySQL / 全数据库通用写法

先子查询查出每个status_type对应的最新创建时间,再关联原表匹配出完整记录:

latest_time_subquery = YourModel
  .group(:status_type)
  .select(:status_type, "MAX(created_at) AS latest_created_at")

result = YourModel
  .joins("INNER JOIN (#{latest_time_subquery.to_sql}) AS latest_match 
          ON latest_match.status_type = #{YourModel.table_name}.status_type 
          AND latest_match.latest_created_at = #{YourModel.table_name}.created_at")
  .where(status_type: ["test", "integer"])

注意:如果同一个status_type下存在多条created_at时间完全一致的记录,通用写法会返回所有同时间的匹配记录。Rails默认生成的created_at带微秒级精度,正常业务场景下几乎不会出现这类冲突,如果有强一致性要求,可以追加主键id的倒序排序规则做二次校验。

内容的提问来源于stack exchange,提问作者Devalo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 07:54:32