2017-07-28 111 views
0

我想删除具有相同norad_cat_id的SQL数据库中的行。由于我的数据库中的数据每天都会更新,因此将添加具有相同norad_cat_id的新行。我想要做的是删除所有具有相同的norad_cat_id的行,只留下最近添加的行。到目前为止,我已经尝试从堆栈溢出(其中没有工作)的几个解决方案:Laravel - 删除SQL数据库中的重复行

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('/'); 
} 

编辑:

I我想我需要给出一个清晰的解释,我想实现的目标是:我的数据库会自动更新。我希望能够做的是创建一个行,如果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')); 

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

+0

你有没有任何主键或唯一的ID在你的表? –

+0

在mysql或sql-server之间进行选择,你不能同时使用 – GuidoG

+0

可以尝试在Laravel中运行raw sql吗?例如 DB :: select(DB :: raw(“SELECT * FROM some_table WHERE some_col ='$ someVariable'”)); 看看如何删除mysql上的重复行; https://stackoverflow.com/questions/4685173/delete-all-duplicate-rows-except-for-one-in-mysql –

回答

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

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++; 
} 
+0

等待,没有阅读有关同一个ID的多个记录,认为只有2个记录具有相同的编辑编辑:完成! – aaron0207

+0

我试过 - 得到一个未定义的变量。 “$ id_to_delete”是什么意思? –

+0

使用所需的ID对其进行初始化以清除重复项(例如,在插入具有所需ID的新记录后,可以使用它) – aaron0207

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

} 

希望这对你的工作!

+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 列在条款“norad_cat_id”不明确

这意味着你必须指定哪些表t他列是指...

参考: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(); 
+0

感谢您的回答,但这仍然不会删除重复的行。现在没有更多的错误。 –

+0

你有什么错误吗?你可以创建一个'sqlfiddle'吗? –

+0

我现在会发布我的完整模型 –