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

e3bfsja2  于 2023-02-18  发布在  Mysql
关注(0)|答案(5)|浏览(168)

我正在尝试删除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中的一个。
我在看这个: www.example.com和www.example.com。也许我可以用这个?https://laravel.com/docs/5.4/eloquent#deleting-models and https://laravel.com/docs/5.4/database#running-queries. Maybe I can use this?

    • 编辑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'));

我看了一些答案和其他问题,试图想出一些东西。

mbskvtky

mbskvtky1#

试试这个,它只保留重复的和非重复的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();

针对业务方案评论:
出现错误-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();
2izufjch

2izufjch2#

假设您使用的是时间戳:

$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++;
}
to94eoyn

to94eoyn3#

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

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的行。

qq24tv8q

qq24tv8q4#

你应该试试这个:

$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();

}

希望这对你有用!

plupiseo

plupiseo5#

$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();

相关问题