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

时间:2019-05-14 01:48:02

标签: ruby-on-rails ruby postgresql

我正在使用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")

这将返回以下数组:

[#<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>]

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

谢谢!

1 个答案:

答案 0 :(得分:5)

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

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

要获取每个具有多个(因此具有重复项)的组的所有ID:

SELECT array_agg(id) FROM log_entries GROUP BY date, athlete_id HAVING count(*) > 1

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

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

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

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

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

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

原始答案:

您的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")