在sql的使用中,咱們老是碰到須要刪除重複數據的狀況,可是又不能所有刪除完,必需要保留至少一個重複的數據。重複的記錄根據兩個字段a2,a3判斷(實際使用中能夠拓展爲多個)sql
a1 | a2 | a3 |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 2 |
4 | 2 | 2 |
5 | 3 | 3 |
6 | 2 | 2 |
select *,count(*) from A group by a2,a3 having count(*)>1;
a1 | a2 | a3 | count(*) |
---|---|---|---|
3 | 2 | 2 | 3 |
SELECT * FROM A WHERE (a2,a3) IN (SELECT A.`a2`,A.`a3` FROM A GROUP BY A.`a2`,A.`a3` HAVING COUNT(*)>1)
a1 | a2 | a3 |
---|---|---|
3 | 2 | 2 |
4 | 2 | 2 |
6 | 2 | 2 |
那麼後面就很好辦了:code
SELECT * FROM A WHERE (a2, a3) IN (SELECT `a2`,`a3` FROM A GROUP BY A.`a2`,A.`a3` HAVING COUNT(*) > 1) AND a1 NOT IN (SELECT MIN(a1) FROM A GROUP BY A.`a2`,A.`a3` HAVING COUNT(*) > 1) ; -- 結果是保留a1最小的值,其餘選項所有選出, -- 請注意此時並非將Select 改成delete就能夠了,若是你直接這樣改的話,會報以下錯誤: -- You can't specify target table 'A' for update in FROM clause -- 該錯誤提示你,不能先select出同一表中的某些值,再update這個表(在同一語句中)。因此要稍微修改一下。
sql語句以下:ci
//建立中間表 CREATE TABLE F(a1 INTEGER,a2 INTEGER,a3 INTEGER); //將要刪除的數據插入中間表 INSERT INTO F ( SELECT * FROM A WHERE (a2, a3) IN (SELECT `a2`,`a3` FROM A GROUP BY A.`a2`,A.`a3` HAVING COUNT(*) > 1) AND a1 NOT IN (SELECT MIN(a1) FROM A GROUP BY A.`a2`,A.`a3` HAVING COUNT(*) > 1)) ; //刪除中間表 DELETE FROM A WHERE a1 IN (SELECT a1 FROM F); SELECT *FROM A;
a1 | a2 | a3 |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 2 |
5 | 3 | 3 |
若是說不用保留一行數據的話那麼就簡單多了,只須要一個很簡單的sql語句:get
DELETE FROM A WHERE (a2,a3) IN (SELECT a2,a3 FROM A GROUP BY a2,a3 HAVING COUNT(*)>1)