2017-07-28 112 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

我現在會發布我的完整模型 –