试图删除数据库中的重复条目,但获取nil id

Gra*_*eme 0 ruby postgresql ruby-on-rails

我正在使用rails find_by_sql查询来查找重复的条目,但是我很难删除它们,因为该查询返回的ID为nil的数组。

LogEntry.find_by_sql("SELECT date, athlete_id, count(*) as qty FROM log_entries GROUP BY date, athlete_id HAVING count(*)> 1")
Run Code Online (Sandbox Code Playgroud)

这将返回以下数组:

[#<LogEntry id: nil, date: "2016-06-12", athlete_id: 49>, #<LogEntry id: nil, date: "2015-09-05", athlete_id: nil>, #<LogEntry id: nil, date: "2015-09-06", athlete_id: nil>, #<LogEntry id: nil, date: "2019-05-02", athlete_id: nil>]
Run Code Online (Sandbox Code Playgroud)

当我尝试添加时,.each(&:destroy)它无法破坏它,因为您可以看到ID列为nil。我不明白的是这怎么可能?这些条目应该能够在没有ID的表中存在。我的SQL查询有问题吗?

谢谢!

fph*_*ipe 5

@engineersmnky发表评论后更新答案(谢谢,错过了分组)。

为了删除重复项,您必须获取重复行的ID。对于每个重复项,您需要N-1个ID,因为一个ID应该留在后面。

要获取具有多个(因此具有重复项)的每个组的所有ID,请执行以下操作:

SELECT array_agg(id) FROM log_entries GROUP BY date, athlete_id HAVING count(*) > 1
Run Code Online (Sandbox Code Playgroud)

让我们省略每个组中的第一个ID:

SELECT (array_agg(id))[2:] FROM log_entries GROUP BY date, athlete_id HAVING count(*) > 1
Run Code Online (Sandbox Code Playgroud)

接下来,我们需要取消嵌套它们,以便获得仅要删除的ID的列表:

SELECT unnest((array_agg(id))[2:]) FROM log_entries GROUP BY date, athlete_id HAVING count(*) > 1
Run Code Online (Sandbox Code Playgroud)

现在,为了将它们加载到Rails中,一个简单.where(..)的ID就在上面构造的结果集中:

LogEntry.where('id IN (SELECT unnest((array_agg(id))[2:]) FROM log_entries GROUP BY date, athlete_id HAVING count(*) > 1)')
Run Code Online (Sandbox Code Playgroud)

原始答案:

SELECT没有选择id。添加id到您的查询,它应该可以工作:

LogEntry.find_by_sql("SELECT id, date, athlete_id, count(*) as qty FROM log_entries GROUP BY date, athlete_id HAVING count(*)> 1")
Run Code Online (Sandbox Code Playgroud)