查询一个表,并获取所有重复行的ID(最好是除了第一个重复实例的ID之外的所有ID)。
现在我有以下mysql语句:
select `codes`, count(`codes`) as `occurrences`, `customer_id` from `pizzas`
group by `codes`, `customer_id`
having `occurrences` > 1;
重复数据是指在
codes
和customer_id
这两列的组合中,有任意行数据相同,例如:codes,customer_id
183665A4,3
183665A4,3
183665A4,3
183665A4,3
183665A4,3
我试图仅保留其中一个,删除其他的。
这会返回代码的集合,包括它们的发生次数和客户ID,因为我只想要同时具有这两个条件的行。
目前我通过循环来实现,保存第一个实例的ID,然后再次调用并删除没有该ID的任何实例。由于我们需要对每个重复的实例进行多次查询以进行删除,因此这似乎不太快,因为有大约5000万行数据,每个查询都需要很长时间。
// get every order that shares the same code and customer ID
$orders = Order::select('id', 'codes', DB::raw('count(`codes`) as `occurrences`'), 'customer_id')
->groupBy('codes')
->groupBy('customer_id')
->having('occurrences', '>', 1)
->limit(100)
->get();
// loop through those orders
foreach ($orders as $order)
{
// find the first order that matches this duplicate set
$first_order = Order::where('codes', $order->codes)
->where('customer_id', $order->customer_id)
->first();
// delete all but the first
Order::where('codes', $order->codes)
->where('customer_id', $order->customer_id)
->where('id', '!=', $first_order->id)
->delete();
}
有一种更有效的方法来跟踪所有具有相同代码和客户ID的行,并删除所有重复项但保留第一个实例,对吧?哈哈
我想也许如果我可以添加一个假列到结果中,该列是每个ID的数组,那么至少我可以删除第一个ID并删除其他ID。
codes
包含什么?unique
逻辑是否是codes
和customer_id
的组合?也许您可以编辑您的问题,并包含来自数据库的一些示例行,以帮助我们更好地可视化它。 - Tim Lewisunique
索引codes|customer_id
,是吧?对于这么多的记录,我的方法与你的方法相同;分批处理,找到重复的数据对,找到第一个数据的id
,然后运行一个单独的DELETE FROM pizzas WHERE id IN ?
语句,其中?
是ID列表减去第一个数据。该语句将运行X次,直到所有重复数据都被删除。然后,请务必添加一个唯一索引。 - Tim Lewis