Laravel - 删除SQL数据库中的重复行

时间:2017-07-28 11:54:07

标签: php mysql sql laravel laravel-5.4

我正在尝试删除SQL数据库中具有相同norad_cat_id的行。由于我的数据库中的数据将每天更新,因此将添加具有相同norad_cat_id的新行。我想要做的是删除具有相同norad_cat_id的所有行,并且只保留最近添加的行。到目前为止,我已经尝试了Stack Overflow的一些解决方案(其中没有一个有效):

1:

DB::table('satellites')->select('norad_cat_id')->distinct()->delete();

2

$deleteDuplicates = DB::table('satellites as n1')
    ->join('satellites as n2', 'n1.norad_cat_id', '>', 'norad_cat_id')
    ->where('n1.norad_cat_id', '=', 'n2.norad_cat_id')
    ->delete();

我的数据库名称是satellite

TL; DR:删除数据库中具有相同norad_cat_id的行

修改

这是我的全部功能:

    public function displayer(){
    $api = new Client([
    'base_uri' => 'https://www.space-track.org',
    'cookies' => true, 
    ]); $api->post('ajaxauth/login', [
      'form_params' => [
         'identity' => '#', 
         'password' => '#', 
     ],
    ]);
    $response = $api->get('basicspacedata/query/class/satcat/orderby/INTLDES%20desc/limit/2/metadata/false');
    $data = json_decode($response->getBody()->getContents(), true);
    foreach ($data as $attributes) {
        $attributes = array_change_key_case($attributes, CASE_LOWER);
        Satellite::create($attributes);
    }
    $deleteDuplicates = DB::table('satellites as n1') 
      ->join('satellites as n2', 'n1.created_at', '<', 'n2.created_at') 
        ->where('n1.created_at', '=', 'n2.created_at') ->delete();
    $api->get('ajaxauth/logout');
    return redirect('/');   
}

修改

我想我需要清楚解释一下我要实现的目标:我的数据库会自动更新。我希望能够做的是,如果数据库中不存在norad_cat_id,则创建一行。如果它已经存在,我希望它使用相同的norad_cat_id行,删除它,并且只使用我在数据库中的时间戳留下最新的行。所以我有一个norad_cat_id

我在看这个:https://laravel.com/docs/5.4/eloquent#deleting-modelshttps://laravel.com/docs/5.4/database#running-queries。也许我可以用这个?

编辑2: 任何人都可以对我写的代码有所了解:

DB::select( DB::raw('DELETE n1 FROM satellites n1, satellites n2 WHERE n1.id < n2.id AND n1.norad_cat_id = n2.norad_cat_id'));

我看了一些答案和其他问题,并试着提出一些建议。

4 个答案:

答案 0 :(得分:1)

试试这个,它只保留重复和非重复的id最新的id和

$deleteDuplicates = DB::table('satellites as n1') 
  ->join('satellites as n2', 'n1.norad_cat_id', '<', 'n2.norad_cat_id') 
    ->where('n1.norad_cat_id', '=', 'n2.norad_cat_id') ->delete();

回应OP评论:

  

收到错误 - SQLSTATE [23000]:完整性约束违规:1052   on子句中的列'norad_cat_id'是不明确的

表示您必须指定列引用的表...

参考:Delete all Duplicate Rows except for One in MySQL?

修改

$ids_to_delete = array(1, 2, 3);
DB::table('satellites')->whereIn('norad_cat_id', $ids_to_delete)->delete();

答案 1 :(得分:0)

假设您正在使用时间戳:

$target_data = DB::table('satellites')->select('norad_cat_id')->where('norad_cat_id',$id_to_delete)->orderBy('created_at','DESC')->get();

$i = 0;
$len = count($target_data );

foreach($target_data as $data){
    if ($i != $len - 1) {
        $data->delete();
    }
    $i++;
}

答案 2 :(得分:0)

你应该试试这个:

$delSatellite = DB::table('satellites')->select('norad_cat_id')->orderBy('created_at','DESC')->get();

foreach($delSatellites as $delSatellite){
  DB::table('satellites')->where('id',$delSatellite->id)->delete();

}

希望这对你有用!!!

答案 3 :(得分:0)

在查看其他答案之后,我发现了最适合我的答案:

DELETE FROM satellites WHERE id NOT IN (SELECT * FROM (SELECT MAX(n.id) FROM satellites n GROUP BY n.norad_cat_id) x)

这会删除具有相同norad_cat_id的所有行,但会留下具有最​​高id的行。