Rails查询Booking表按date和class_id分组去重的实现方法
问题核心
你需要对bookings表按date、class_id两个字段去重,每组仅保留id最小的一条完整记录。
方案1:PostgreSQL 环境最简写法
利用PostgreSQL特有的DISTINCT ON语法,一步完成查询:
bookings = Booking.select('DISTINCT ON (date, class_id) *').order(:date, :class_id, :id)
- 逻辑说明:
DISTINCT ON (date, class_id)指定按这两个字段分组去重,order规则里最后按id升序排序,保证每组取到的是id最小的那条记录,返回结果和你给出的预期完全一致。
方案2:全数据库兼容写法(支持MySQL、SQLite、PostgreSQL)
如果应用需要兼容多种数据库,可分两步查询:
# 第一步:查询每个(date, class_id)分组下的最小id min_ids_per_group = Booking.group(:date, :class_id).pluck(Arel.sql('MIN(id)')) # 第二步:根据最小id列表查询完整的预约记录 bookings = Booking.where(id: min_ids_per_group).order(id: :asc)
- 逻辑说明:先通过分组聚合拿到每组要保留的id,再批量查询完整记录,执行效率高,适配所有常见关系型数据库。
内容的提问来源于stack exchange,提问作者Gerald
相关产品推荐
相关产品推荐

