情景:
我們的數據庫中可能會存在很多因各種原因而重復的記錄,我們需要對這些重復的記錄進行刪除,每組組重復的記錄只保留一條就行
例如我們有這么個表:兩個框框都是有重復記錄的,紅框和綠框都只需要留下一條,其他的都干掉。
前提:
1:每天記錄都要有一個唯一id
2:每組重復的記錄要有字段能進行分組,例如上面我們按name、class、age、score相同的就是一組。
數據寶貴,請先備份!!!
數據寶貴,請先備份!!!
數據寶貴,請先備份!!!
放上整條SQL:
DELETE FROM "t_hw_test_del" t3 WHERE 1 = 1 AND EXISTS ( SELECT * FROM ( SELECT "id","name","class","age","score" FROM "t_hw_test_del" WHERE 1 = 1 )t1 LEFT JOIN ( SELECT "MAX"("id") as "id","name","class","age","score" FROM "t_hw_test_del" WHERE 1 = 1 GROUP BY "name","class","age","score" ) t2 ON t1."id" = t2."id" AND t1."name" = t2."name" AND t1."class" = t2."class" AND t1."age" = t2."age" AND t1."score" = t2."score" WHERE t2."id" is NULL AND t1."id" = t3."id" )
按步分析:
1:找到我們需要的記錄,因為我們可能只是要處理某天的記錄,所以要先篩選一下,我這里用1=1來代替
SELECT * FROM "t_hw_test_del" WHERE 1 = 1
2:找到我們每一組要保留的記錄 ,我這里選每組id最大的保留,其他的不要
SELECT "MAX"("id") as "id","name","class","age","score" FROM "t_hw_test_del" WHERE 1 = 1 GROUP BY "name","class","age","score"
3:用我們找到的需要處理的記錄和要保留的記錄關聯起來, 用分組字段和唯一id關聯,左聯
SELECT * FROM ( SELECT "id","name","class","age","score" FROM "t_hw_test_del" WHERE 1 = 1 )t1 LEFT JOIN ( SELECT "MAX"("id") as "id","name","class","age","score" FROM "t_hw_test_del" WHERE 1 = 1 GROUP BY "name","class","age","score" ) t2 ON t1."id" = t2."id" AND t1."name" = t2."name" AND t1."class" = t2."class" AND t1."age" = t2."age" AND t1."score" = t2."score"
4:右表為null的記錄,對應的左表記錄就是我們要刪掉的,加個條件右表為null
SELECT * FROM ( SELECT "id","name","class","age","score" FROM "t_hw_test_del" WHERE 1 = 1 )t1 LEFT JOIN ( SELECT "MAX"("id") as "id","name","class","age","score" FROM "t_hw_test_del" WHERE 1 = 1 GROUP BY "name","class","age","score" ) t2 ON t1."id" = t2."id" AND t1."name" = t2."name" AND t1."class" = t2."class" AND t1."age" = t2."age" AND t1."score" = t2."score" WHERE t2."id" is NULL
5: 用我們原來的記錄id在我們不需要的記錄里面找,如果這條記錄在我們不需要的記錄集里,那這條記錄就可以刪除
DELETE FROM "t_hw_test_del" t3 WHERE 1 = 1 AND EXISTS ( SELECT * FROM ( SELECT "id","name","class","age","score" FROM "t_hw_test_del" WHERE 1 = 1 )t1 LEFT JOIN ( SELECT "MAX"("id") as "id","name","class","age","score" FROM "t_hw_test_del" WHERE 1 = 1 GROUP BY "name","class","age","score" ) t2 ON t1."id" = t2."id" AND t1."name" = t2."name" AND t1."class" = t2."class" AND t1."age" = t2."age" AND t1."score" = t2."score" WHERE t2."id" is NULL AND t1."id" = t3."id" )
6: 檢查一下結果符不符合我們的要求
SELECT "id","name","class","age","score" FROM "t_hw_test_del" WHERE 1 = 1