我正在尝试删除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-models和https://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'));
我看了一些答案和其他问题,并试着提出一些建议。
答案 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
的行。