我需要根据uniq inspection_id 过滤主记录
Home.all.select(:id,:inspection_id)
[#<Home:0x007fc5cd065758 id: 2192, inspection_id: 21967>,
#<Home:0x007fc5cd065618 id: 2191, inspection_id: 21968>,
#<Home:0x007fc5cd0654d8 id: 2190, inspection_id: 21967>,
#<Home:0x007fc5cd065398 id: 2189, inspection_id: 21968>,
#<Home:0x007fc5cd065258 id: 2188, inspection_id: 21963>,
#<Home:0x007fc5cd065118 id: 2187, inspection_id: 21967>]
需要这样的结果
[#<Home:0x007fc5cd065758 id: 2192, inspection_id: 21967>,
#<Home:0x007fc5cd065618 id: 2191, inspection_id: 21968>,
#<Home:0x007fc5cd065118 id: 2188, inspection_id: 21963>]
家与ID2191,2191,2188
,我需要在结果集
我试过了,但不起作用。
Home.all.select(:id,:inspection_id).distinct
给出此错误
ORDER BY子句的表达式#1不在SELECT列表中,引用的列"myDB.homes.created_at"不在SELECT名单中;这与DISTINCT 不兼容我下一步可以尝试什么?
您没有指定RDBMS,但在PostgreSQL中可以使用DISTINCT ON
Home.select('DISTINCT ON (inspection_id) *')
首先,我认为这不是一个有效的SQL语句。DISTINCT将处理SELECT子句中定义的所有列,并将返回所有记录,因为所有列的ID都不同。使用GROUP是更好的选择。
Home.all.select(:id, :inspection_id).group(:inspection_id)
这将按inspection_ids对所有记录进行分组,如果您在上面的查询中调用to_a
,您将只得到有效的记录。您也可以对上面的记录进行迭代。
另一种选择是,如果您不期望有很多行——只需使用Home.all.pluck(:id, :inspection_id)
并在rails端执行唯一逻辑——但如果您有成千上万的行,这不是一个好的解决方案——这将把所有记录加载到内存中。
Udit的代码看起来不错,但需要进行一些更改。尝试以下代码:
Home.all.order(: inspection_id, :id).select('DISTINCT ON (inspection_id) id, inspection_id')
您可以使用窗口函数ROW_NUMBER()
来按inspection_id
标记每组的顶部记录(按id排序(,然后只需选择这些顶部记录:
ActiveRecord::Base.connection.execute <<~SQL
SELECT w.id, w.inspection_id
FROM(
SELECT
id, inspection_id,
ROW_NUMBER() OVER (PARTITION BY inspection_id ORDER BY id DESC) AS row
FROM homes
) w
WHERE w.row = 1
SQL