如何获得基于Ruby两个字段的唯一记录



我需要根据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

相关内容

  • 没有找到相关文章

最新更新