使用Laravel的查询构建器返回完整的重复行

时间:2015-10-13 08:36:44

标签: php mysql laravel inner-join query-builder

我希望从表中返回有关重复记录的完整信息。

我目前正在使用以下内容:

DB::table($entity['table'])
                ->select('*')
                ->groupBy($entity['columns'])
                ->havingRaw('COUNT(*) > 1')
                ->get();

哪个好,它返回重复记录,但是,这只返回我需要返回所有重复项的记录之一,以便我可以选择要删除或保留哪一个用户。

如何修改上述查询才能完成?

3 个答案:

答案 0 :(得分:1)

加入同一个表将允许您检索重复的记录,而不只是获取它的单个版本(由您的问题中的groupBy引起)

$entity['columns'] = ['username', 'surname'];

$groupBy = implode(',', $entity['columns']);

$subQuery = DB::table('list')
    ->select('*')
    ->groupBy($groupBy)
    ->havingRaw('(count(id) > 1))');

$result = DB::table('list')
    ->select('*')
    ->join(
        DB::raw("({$subQuery->toSql()}) dup"), function($join) use ($entity) {
            foreach ($entity['columns'] as $column) {
                $join->on('list.'.$column, '=', 'dup.'.$column);
            }
        })
    ->toSql();
    // or ->get(); obviously

    dd($result);

答案 1 :(得分:0)

您需要在$ entity ['columns']中的列上联接回$ entity ['table']中的表格以获取重复项。

此外,即使您使用的是mysql,选择('*')也不是一个好主意。这是针对sql标准的,只有在以某种方式配置时才在mysql中工作。如果配置更改或您将应用程序迁移到sql模式下具有不同配置的mysql服务器,则查询将失败。

我也会在选择列表中使用$ entity ['columns']。

在sql中,查询应如下所示:

select table.* from table inner join
  (select field1, field2 from table t
  group by field1, field2
  having count(*)>1) t1
on table.field1=t1.field1 and table.field2=t1.field2

答案 2 :(得分:0)

您可以使用whereIn和一个函数来查询正在使用的同一张表来完成此操作。

假设您有一种情况,您希望在用户表中查找包含相同姓氏的重复记录。

数据库表-用户

      --- user_id --- first_name --- last_name --- email ---

            1           Dan           Smith     dan@test.com
            2           Jim           Jones     jim@test.com
            3           Amy           Grant     amy@test.com
            4           Bob           Brown     bob@test.com
            5           Sue           Davis     sue@test.com
            6           Leo           Grant     leo@test.com
            7           Ann           Grant     ann@test.com

然后您可以使用以下代码;

 $duplicates = DB::table('user')
 ->select('user_id', 'last_name')
 ->whereIn('user_id', function ($q){
             $q->select('user_id')
             ->from('user')
             ->groupBy('last_name')
             ->havingRaw('COUNT(*) > 1');
 })->get();

将返回以下内容;

      --- user_id --- last_name

            3           Grant
            6           Grant
            7           Grant