【问题标题】:Eloquent - Detect multiple column duplicate dataEloquent - 检测多列重复数据
【发布时间】:2019-09-07 00:17:52
【问题描述】:

我有一个包含 3 列 id, sub_id, name 的表。那是一张很大的桌子,而且有一些重复。

检测重复项以便我可以删除它们的最佳方法是什么?

我试过了,但它会返回所有内容(我猜想 id 会让它们变得不唯一)

$collection = \App\MyModel::all();
$colUnique = $collection->unique(['name', 'sub_id']);
$dupes = $collection->diff($colUnique);

我想获得具有相同namesub_id 的模型。

id    sub_id   name
1       2      John
2       2      John   <- duplicate
3       2      Robin  <- unique

【问题讨论】:

  • 为什么不使用 toArray() 函数并通过运行 php 函数 array_unique 和 array_diff 获取所有重复条目,然后运行 ​​foreach 循环并删除它们。
  • 或者如果你想在检索模型时使用 SQL 方式使用 groupBy 函数。

标签: laravel eloquent query-builder laravel-collection


【解决方案1】:

我最好的选择是 DB::Query。

第 1 步:按分组获取数据

$uniqueData = DB::table('TABLE_NAME')
                  ->groupBy(['sub_id', 'name'])
                  ->select('id')
                  ->toArray();

第 2 步:删除重复记录。

$noOfDeletedRecords = DB::table('TABLE_NAME')
                          ->whereNotIn($uniqueData)
                          ->delete();

好处: 1.只有2个查询 2. 比收集更好的性能。

【讨论】:

  • 虽然这种方法更有效,但如果模型删除了观察者/处理程序,它可能会引发问题。另外,您应该选择MIN(id)
  • 需要稍作改动,但 +1 以获得更好的性能。性能是关键。
  • @Styx 是的,我同意你的看法。在观察者/处理程序的情况下,这种方法是有问题的。有一种解决方法,而不是 DB 直接使用模型。即`MyModel::whereNotIn($ARRAY)-&gt;delete()。问题解决了。 :D
  • @RutvijKothari 我只是指 Styx 的回复。我喜欢你的方式..不用担心。
【解决方案2】:

您可以使用Collection.groupBy 方法。

$collection = \App\MyModel::all();

$collection
  // Group models by sub_id and name
  ->groupBy(function ($item) { return $item->sub_id.'_'.$item->name; })
  // Filter to remove non-duplicates
  ->filter(function ($arr) { return $arr->count()>1; })
  // Process duplicates groups
  ->each(function ($arr) {
    $arr
      // Sort by id  (so first item will be original)
      ->sortBy('id')
      // Remove first (original) item from dupes collection
      ->splice(1)
      // Remove duplicated models from DB
      ->each(function ($model) {
        $model->delete();
      });
  })

【讨论】:

  • 从性能的角度来看,调用\App\MyModel::all();,把所有的模型都拿到内存中确实是一件很糟糕的事情……
  • @AnixPasBesoin 这取决于。
猜你喜欢
  • 2021-09-07
  • 2021-10-28
  • 2022-01-01
  • 2022-01-19
  • 2014-08-23
  • 1970-01-01
  • 2012-05-08
  • 2021-08-16
  • 1970-01-01
相关资源
最近更新 更多