mysql數(shù)據(jù)庫(kù)刪除重復(fù)數(shù)據(jù)只保留一條方法實(shí)例
1.問(wèn)題引入
假設(shè)一個(gè)場(chǎng)景,一張用戶表,包含3個(gè)字段。id,identity_id,name?,F(xiàn)在身份證號(hào)identity_id和姓名name有很多重復(fù)的數(shù)據(jù),需要?jiǎng)h除只保留一條有效數(shù)據(jù)。
2.模擬環(huán)境
1.登入mysql數(shù)據(jù)庫(kù),創(chuàng)建一個(gè)單獨(dú)的測(cè)試數(shù)據(jù)庫(kù)mysql_exercise
create database mysql_exercise charset utf8;
2.創(chuàng)建用戶表users
create table users( id int auto_increment primary key, identity_id varchar(20), name varchar(20) not null );
3.插入測(cè)試數(shù)據(jù)
insert into users values(0,'620616199409206512','張三'), (0,'620616199409206512','張三'), (0,'62062619930920651X','李四'), (0,'62062619930920651X','李四'), (0,'620622199101206211','王五'), (0,'620622199101206211','王五'), (0,'322235199909116233','趙六');
可以多執(zhí)行幾次,生成較多重復(fù)數(shù)據(jù)。
4.解決思路
(1)根據(jù)身份證號(hào)和name進(jìn)行分組;
(2)取出分組后的最大id(或最小id);
(3)刪除除最大(或最小)id以外的其他字段;
5.第一次嘗試(失敗!!!)
delete from users where id not in (select max(id) from users group by identity_id,name);
報(bào)錯(cuò):
1093 (HY000): You can't specify target table 'users' for update in FROM clause
因?yàn)樵贛YSQL里,不能先select一個(gè)表的記錄,再按此條件進(jìn)行更新和刪除同一個(gè)表的記錄。
解決辦法是,將select得到的結(jié)果,再通過(guò)中間表select一遍,這樣就規(guī)避了錯(cuò)誤,
這個(gè)問(wèn)題只出現(xiàn)于mysql,mssql和oracle不會(huì)出現(xiàn)此問(wèn)題。
所以我們可以先將括號(hào)里面的sql語(yǔ)句先拿出來(lái),先查到最大(或最?。﹊d。
select max_id from (select max(id) as max_id from users group by identity_id,name);
接著,又報(bào)錯(cuò)了?。?!
ERROR 1248 (42000): Every derived table must have its own alias
意思是說(shuō):提示說(shuō)每一個(gè)衍生出來(lái)的表,必須要有自己的別名!
執(zhí)行子查詢的時(shí)候,外層查詢會(huì)將內(nèi)層的查詢當(dāng)做一張表來(lái)處理,所以我們需要給內(nèi)層的查詢加上別名
繼續(xù)更正:
給查詢到的最大(或最小id)結(jié)果當(dāng)做一張新的表,起別名t,并查詢t.mix_id。
select t.max_id from (select max(id) as max_id from users group by identity_id,name) as t;
可以成功查到最大(或最?。﹊d了,如下圖:
6.第二次嘗試(成功?。。。?/strong>
delete from users where id not in ( select t.max_id from (select max(id) as max_id from users group by identity_id,name) as t );
執(zhí)行結(jié)果:
成功將重復(fù)的數(shù)據(jù)刪除,只保留了最后一次增加的記錄。同理也可以保留第一次添加的記錄(即刪除每個(gè)分組里面除最小id以外的其他條記錄)
3.知識(shí)拓展一:更新數(shù)據(jù)
其他場(chǎng)景應(yīng)用:要將用戶表user_info里名字(name)為空字符串("")的用戶的狀態(tài)(status)改成"0"
update user_info set status='0' where user_id in (select user_id from user_info where name='')
同樣報(bào)了如下錯(cuò)誤:
You can't specify target table ‘user_info' for update in FROM clause
因?yàn)樵贛YSQL里,不能先select一個(gè)表的記錄,再按此條件進(jìn)行更新和刪除同一個(gè)表的記錄,解決辦法是,將select得到的結(jié)果,再通過(guò)中間表select一遍,這樣就規(guī)避了錯(cuò)誤。
以下兩種均可!??!
update user_info set status='0' where user_id in (select user_id from (select user_id from user_info where name = '') t1);
下面這種也可,細(xì)微差別,別名可帶as可不帶,t1.user_id 直接和內(nèi)層的user_id對(duì)應(yīng)也可以。
update user_info set status='0' where user_id in (select t1.user_id from (select user_id from user_info where name='') as t1);
3.1 分步驟解析
(1)將以下查詢結(jié)果作為中間表:
select user_id from user_info where name='';
(2)再查詢一遍中間表作為結(jié)果集:
select user_id from (select user_id from user_info where name='') as t;
(3)更新數(shù)據(jù)
update user_info set status='0' where user_id in (select user_id from (select user_id from user_info where name='') as t1);
4.拓展練習(xí):刪除重復(fù)數(shù)據(jù)
編寫(xiě)一個(gè) SQL 查詢,來(lái)刪除 Person 表中所有重復(fù)的電子郵箱,重復(fù)的郵箱里只保留 Id 最小 的那個(gè)。
+----+------------------+ | Id | Email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | | 3 | john@example.com | +----+------------------+
Id 是這個(gè)表的主鍵。
例如,在運(yùn)行你的查詢語(yǔ)句之后,上面的 Person 表應(yīng)返回以下幾行:
+----+------------------+ | Id | Email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | +----+------------------+
解答一:
delete from Person where Id not in ( select t.min_id from ( select min(Id) as min_id from Person group by Email ) as t );
解答二:
delete p1 from Person as p1,Person as p2 where p1.Email=p2.Email and p1.Id > p2.Id;
總結(jié)
到此這篇關(guān)于mysql數(shù)據(jù)庫(kù)刪除重復(fù)數(shù)據(jù)的方法只保留一條的文章就介紹到這了,更多相關(guān)mysql刪除重復(fù)數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MySQL數(shù)據(jù)庫(kù)中刪除重復(fù)記錄的方法總結(jié)[推薦]
- sqlserver中重復(fù)數(shù)據(jù)值只取一條的sql語(yǔ)句
- sql刪除重復(fù)數(shù)據(jù)的詳細(xì)方法
- mysql查找刪除重復(fù)數(shù)據(jù)并只保留一條實(shí)例詳解
- MySQL根據(jù)某一個(gè)或者多個(gè)字段查找重復(fù)數(shù)據(jù)的sql語(yǔ)句
- Mysql?刪除重復(fù)數(shù)據(jù)保留一條有效數(shù)據(jù)(最新推薦)
- oracle/mysql數(shù)據(jù)庫(kù)多條重復(fù)數(shù)據(jù)如何取最新的
相關(guān)文章
CentOS7.x卸載與安裝MySQL5.7的操作過(guò)程及編碼格式的修改方法
這篇文章主要介紹了CentOS7.x卸載與安裝MySQL5.7的操作過(guò)程及編碼格式的修改方法,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05MySQL實(shí)現(xiàn)創(chuàng)建存儲(chǔ)過(guò)程并循環(huán)添加記錄的方法
這篇文章主要介紹了MySQL實(shí)現(xiàn)創(chuàng)建存儲(chǔ)過(guò)程并循環(huán)添加記錄的方法,涉及基本的mysql存儲(chǔ)過(guò)程創(chuàng)建、調(diào)用相關(guān)操作技巧,需要的朋友可以參考下2017-05-05mysql 協(xié)議的ping命令包及解析詳解及實(shí)例
這篇文章主要介紹了mysql 協(xié)議的ping命令包及解析詳解及實(shí)例的相關(guān)資料,這里附有簡(jiǎn)單實(shí)例代碼并附下載源碼,需要的朋友可以參考下2017-01-01mysqlreport顯示Com_中change_db占用比例高的問(wèn)題的解決方法
最近公司的mysql服務(wù)器經(jīng)常出現(xiàn)阻塞狀態(tài)。動(dòng)不動(dòng)就重啟,給用戶訪問(wèn)帶來(lái)了相當(dāng)?shù)牟槐恪?/div> 2009-05-05詳解MySQL的limit用法和分頁(yè)查詢語(yǔ)句的性能分析
本篇文章主要介紹了詳解MySQL的limit用法和分頁(yè)查詢語(yǔ)句的性能分析,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03使用Mycat-eye管理Mycat數(shù)據(jù)庫(kù)服務(wù)的操作
MyCat是一個(gè)開(kāi)源的分布式數(shù)據(jù)庫(kù)系統(tǒng),是一個(gè)實(shí)現(xiàn)了MySQL協(xié)議的服務(wù)器,前端用戶可以把它看作是一個(gè)數(shù)據(jù)庫(kù)代理,用MySQL客戶端工具和命令行訪問(wèn),本文給大家介紹了使用Mycat-eye管理Mycat數(shù)據(jù)庫(kù)服務(wù)的操作,需要的朋友可以參考下2024-04-04MySql數(shù)據(jù)引擎簡(jiǎn)介與選擇方法
在MySQL 5.1中,MySQL AB引入了新的插件式存儲(chǔ)引擎體系結(jié)構(gòu),允許將存儲(chǔ)引擎加載到正在運(yùn)新的MySQL服務(wù)器中2012-11-11MySQL基礎(chǔ)教程第一篇 mysql5.7.18安裝和連接教程
這篇文章主要為大家詳細(xì)介紹了MySQL基礎(chǔ)教程第一篇,mysql5.7.18安裝和連接教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05mysql優(yōu)化之慢查詢分析+explain命令分析+優(yōu)化技巧總結(jié)
這篇文章主要介紹了mysql優(yōu)化之慢查詢分析,explain命令分析,優(yōu)化技巧總結(jié),需要的朋友可以參考下2023-02-02最新評(píng)論