我正在使用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查询有问题吗?
谢谢!
答案 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")