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

Rails多表查询:如何按供应商ID分组仅返回单条最新记录?

解决供应商最新价格记录重复问题

问题核心

你当前的查询会拉取所有符合item_id=1且item_code不为空的价格记录,所以同一供应商有多条价格记录时就会重复出现。直接用group(:id)报错是因为SQL的分组规则:SELECT的字段要么是分组字段,要么是聚合函数,强行把item_code加入分组又会把同一供应商不同item_code的记录分开,达不到去重效果。

解决方案

方案1:子查询筛选最新价格记录ID

先找出每个供应商对应目标商品的最新价格记录ID,再关联供应商查询:

# 第一步:获取每个供应商对应item_id=1的最新价格记录ID
latest_price_ids = Price.where(item_id: 1)
                        .where.not(item_code: nil)
                        .group(:supplier_id)
                        .maximum(:created_at)
                        .flat_map do |supplier_id, max_created_at|
                          Price.where(
                            supplier_id: supplier_id,
                            created_at: max_created_at,
                            item_id: 1
                          ).pluck(:id)
                        end

# 第二步:关联供应商,获取去重后的结果
Supplier.joins(:prices)
        .where(prices: { id: latest_price_ids })
        .pluck(:id, :item_code)

这个思路先通过group(:supplier_id)拿到每个供应商的最新价格创建时间,再匹配对应的价格记录ID,最后关联供应商,确保每个供应商只返回一条最新记录。

方案2:用窗口函数(适合PostgreSQL/MySQL 8+等支持窗口函数的数据库)

窗口函数可以直接给每个供应商的价格记录按创建时间排序,取第一条:

Supplier.joins(<<-SQL)
  INNER JOIN (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY supplier_id ORDER BY created_at DESC) AS row_num
    FROM prices
    WHERE item_id = 1 AND item_code IS NOT NULL
  ) latest_prices ON suppliers.id = latest_prices.supplier_id AND latest_prices.row_num = 1
SQL
.pluck(:id, :latest_prices_item_code)

这里用ROW_NUMBER()按供应商分组,每组内按created_at降序编号,取row_num=1的就是每个供应商的最新价格记录,关联后自然不会有重复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:45:36