mysql刪除重復(fù)記錄并且只保留一條的實(shí)現(xiàn)方法
準(zhǔn)備的測(cè)試表結(jié)構(gòu)及數(shù)據(jù)
插入的數(shù)據(jù)中A,B,E存在重復(fù)數(shù)據(jù),C沒(méi)有重復(fù)記錄
CREATE TABLE `tab` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tab
-- ----------------------------
INSERT INTO `tab` VALUES ('1', 'A');
INSERT INTO `tab` VALUES ('2', 'A');
INSERT INTO `tab` VALUES ('3', 'A');
INSERT INTO `tab` VALUES ('4', 'B');
INSERT INTO `tab` VALUES ('5', 'B');
INSERT INTO `tab` VALUES ('6', 'C');
INSERT INTO `tab` VALUES ('7', 'B');
INSERT INTO `tab` VALUES ('8', 'B');
INSERT INTO `tab` VALUES ('9', 'B');
INSERT INTO `tab` VALUES ('10', 'E');
INSERT INTO `tab` VALUES ('11', 'E');
INSERT INTO `tab` VALUES ('12', 'E');使用HAVING關(guān)鍵字篩選出表中重復(fù)數(shù)據(jù)
SELECT `name`,COUNT(1) FROM TAB GROUP BY `name` HAVING COUNT(1) >1

可以通過(guò)分組語(yǔ)句從每種重復(fù)數(shù)據(jù)中都拿出一條標(biāo)識(shí)
SELECT `name`,id FROM TAB GROUP BY `name` HAVING COUNT(1) >1

刪除重復(fù)記錄并且只保留一條 [留意SQL注釋]
DELETE from tab where
-- 刪除所有的重復(fù)時(shí)間 Begin --
`name` in (
SELECT * from (SELECT `name`FROM TAB GROUP BY `name` HAVING COUNT(1) >1) tmp2
)
-- 刪除所有的重復(fù)時(shí)間 END --
-- 但一些特定ID的記錄不進(jìn)行刪除 Begin --
AND
id NOT in(
select id from (
SELECT `name`,id FROM TAB GROUP BY `name` HAVING COUNT(1) >1
) tmp1
)
-- 但一些特定ID的記錄不進(jìn)行刪除 END --
執(zhí)行后最終結(jié)果

方法二
MySql如何刪除所有多余的重復(fù)數(shù)據(jù)
方法一查詢出的所有多余的重復(fù)記錄:
方法二查詢出的所有多余的重復(fù)記錄(與方法一的結(jié)果相同):
方法三查詢出的所有多余的重復(fù)記錄:這里方法三因?yàn)橛昧薓AX()方法(也可改用MIN()),查詢結(jié)果記錄的id不太一樣,但也可以被視為重復(fù)多余的數(shù)據(jù),關(guān)鍵是你希望選擇保留哪一條記錄而已。
MySql如何刪除所有多余的重復(fù)數(shù)據(jù) 需要處理的數(shù)據(jù),如:

出現(xiàn)重復(fù)的數(shù)據(jù),如:

先用SELECT查詢看看結(jié)果:
-- 方法一 SELECT * FROM t_user WHERE user_name IN ( SELECT user_name FROM t_user GROUP BY user_name HAVING COUNT(1)>1 ) AND id NOT IN ( SELECT MIN(id) FROM t_user GROUP BY user_name HAVING COUNT(1)>1 )
方法一查詢出的所有多余的重復(fù)記錄:

-- 方法二 SELECT * FROM t_user WHERE id NOT IN ( SELECT MIN(id) FROM t_user GROUP BY user_name )
方法二查詢出的所有多余的重復(fù)記錄(與方法一的結(jié)果相同):

-- 方法三 SELECT * FROM t_user AS t1 WHERE t1.id <> ( SELECT MAX(t2.id) FROM t_user AS t2 WHERE t1.user_name=t2.user_name )
方法三查詢出的所有多余的重復(fù)記錄:

這里方法三因?yàn)橛昧薓AX()方法(也可改用MIN()),查詢結(jié)果記錄的id不太一樣,但也可以被視為重復(fù)多余的數(shù)據(jù),關(guān)鍵是你希望選擇保留哪一條記錄而已。
下面是對(duì)上面的SELECT語(yǔ)句稍作修改并加入了DELETE
-- 方法一(笨方法但容易理解)
DELETE FROM t_user WHERE user_name IN (
SELECT t1.user_name FROM (
-- 查詢出所有重復(fù)的user_name
SELECT user_name FROM t_user GROUP BY user_name HAVING COUNT(1)>1
) t1
)
AND id NOT IN (
SELECT t2.min_id FROM (
-- 查詢出所有重復(fù)的記錄并各自只取其中一條(MIN(id)或MAX(id)都可以)
SELECT MIN(id) AS min_id FROM t_user GROUP BY user_name HAVING COUNT(1)>1
) t2
)
-- 方法二(推薦方法也容易理解)
DELETE FROM t_user WHERE id NOT IN (
SELECT t.min_id FROM (
-- 過(guò)濾出重復(fù)多余的數(shù)據(jù),比如,如果所有記錄中存在1條記錄是user_name=zhangsan的,那么就取出它;
-- 如果所有記錄中存在多條記錄是user_name=lisi的,那么只取其中1條,其他的不查詢出來(lái)
SELECT MIN(id) AS min_id FROM t_user GROUP BY user_name
) t
)
-- 方法三(推薦方法但不太容易理解)
DELETE FROM t_user WHERE id IN (
SELECT t.id FROM (
-- 1. 關(guān)于所有存在相同user_name的記錄,只查詢出(保留)重復(fù)記錄中的1條,假設(shè)這樣查詢出來(lái)的集合為A集合。
-- 2. 在所有記錄中,只要id不在A集合中的,都把它們查詢出來(lái)
SELECT t1.id FROM t_user AS t1 WHERE t1.id <> (SELECT MAX(t2.id) FROM t_user AS t2 WHERE t1.user_name=t2.user_name)
) t
)
-- 或
DELETE FROM t_user t1
WHERE t1.id <> (
SELECT t2.max_id FROM (
SELECT MAX(t3.id) AS max_id FROM t_user t3 WHERE t1.user_name=t3.user_name
) t2
)最后刪除成功之后,顯示數(shù)據(jù)已經(jīng)沒(méi)有重復(fù)的了
參考:
如何實(shí)現(xiàn) MySQL 中通過(guò)SQL語(yǔ)句刪除重復(fù)記錄并且只保留一條記錄
到此這篇關(guān)于mysql刪除重復(fù)記錄并且只保留一條的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)mysql刪除重復(fù)記錄 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
windows下mysql 5.7.20 安裝配置方法圖文教程
這篇文章主要為大家詳細(xì)介紹了windows下mysql 5.7.20 安裝配置方法圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09
java實(shí)現(xiàn)mysql自動(dòng)更新創(chuàng)建時(shí)間與更新時(shí)間的兩種方式
在實(shí)際開(kāi)發(fā)中,每條數(shù)據(jù)的創(chuàng)建時(shí)間和修改時(shí)間,盡量不需要應(yīng)用程序去記錄,而由數(shù)據(jù)庫(kù)獲取當(dāng)前時(shí)間自動(dòng)記錄創(chuàng)建時(shí)間,本文主要介紹了java實(shí)現(xiàn)mysql自動(dòng)更新創(chuàng)建時(shí)間與更新時(shí)間的兩種方式,感興趣的可以了解一下2024-01-01
InnoDB數(shù)據(jù)庫(kù)死鎖問(wèn)題處理
本文給大家講解的是mysql數(shù)據(jù)庫(kù)InnoDB類型,在update表的時(shí)候出現(xiàn)死鎖現(xiàn)象的原因及解決辦法,有需要的小伙伴可以參考下。2016-03-03
mysql 實(shí)現(xiàn)設(shè)置多個(gè)主鍵的操作
這篇文章主要介紹了mysql 實(shí)現(xiàn)設(shè)置多個(gè)主鍵的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
深入了解MySQL鎖機(jī)制及應(yīng)用場(chǎng)景
MySQL鎖是操作MySQL數(shù)據(jù)庫(kù)時(shí)常用的一種機(jī)制。MySQL鎖可以保證多個(gè)用戶在同時(shí)執(zhí)行讀寫(xiě)操作時(shí),能夠互相協(xié)同、避免數(shù)據(jù)出現(xiàn)不一致或者讀寫(xiě)沖突等問(wèn)題。本篇文章將詳細(xì)介紹MySQL鎖的基本知識(shí)和具體應(yīng)用2023-03-03
詳解MySQL導(dǎo)出指定表中的數(shù)據(jù)的實(shí)例
這篇文章主要介紹了詳解MySQL導(dǎo)出指定表中的數(shù)據(jù)的實(shí)例的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09

