可以利用distinct關(guān)鍵字對需要處理的字段進(jìn)行去重

盤山網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、自適應(yīng)網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。成都創(chuàng)新互聯(lián)公司從2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。
使用group by關(guān)鍵字對去重?cái)?shù)據(jù)進(jìn)行去重查詢,針對某個(gè)字段查詢,直接group by 這個(gè)字段
在group by 的基礎(chǔ)上 也可以使用 having 對查詢結(jié)果進(jìn)行二次篩選
MySQL 過濾重復(fù)數(shù)據(jù)
有些 MySQL 數(shù)據(jù)表中可能存在重復(fù)的記錄,有些情況我們允許重復(fù)數(shù)據(jù)的存在,但有時(shí)候我們也需要?jiǎng)h除這些重復(fù)的數(shù)據(jù)。
如果你需要讀取不重復(fù)的數(shù)據(jù)可以在 SELECT 語句中使用 DISTINCT 關(guān)鍵字來過濾重復(fù)數(shù)據(jù)。
from 樹懶學(xué)堂- 一站式數(shù)據(jù)知識學(xué)習(xí)平臺(tái)
你也可以使用 GROUP BY 來讀取數(shù)據(jù)表中不重復(fù)的數(shù)據(jù):
MySQL 刪除重復(fù)數(shù)據(jù)
有些 MySQL 數(shù)據(jù)表中可能存在重復(fù)的記錄,有些情況我們允許重復(fù)數(shù)據(jù)的存在,但有時(shí)候我們也需要?jiǎng)h除這些重復(fù)的數(shù)據(jù)。
本章節(jié)我們將為大家介紹如何防止數(shù)據(jù)表出現(xiàn)重復(fù)數(shù)據(jù)及如何刪除數(shù)據(jù)表中的重復(fù)數(shù)據(jù)。
刪除重復(fù)數(shù)據(jù)
如果你想刪除數(shù)據(jù)表中的重復(fù)數(shù)據(jù),你可以使用以下的SQL語句:
from 樹懶學(xué)堂 - 一站式數(shù)據(jù)知識平臺(tái)
當(dāng)然你也可以在數(shù)據(jù)表中添加 INDEX(索引) 和 PRIMAY KEY(主鍵)這種簡單的方法來刪除表中的重復(fù)記錄。方法如下:
首先是將數(shù)據(jù)庫里邊的重復(fù)記錄刪掉,我看網(wǎng)上有好多答案是這樣的:
1 delete from people
2 where peopleId in (select peopleId from people group by peopleId having count(peopleId) 1)
3 and rowid not in (select min(rowid) from people group by peopleId having count(peopleId )1)
但其實(shí)我每次運(yùn)行這條語句都是行不通的,會(huì)報(bào)錯(cuò):
SQL 錯(cuò)誤 [1093] [HY000]: You can't specify target table 'test1' for update in FROM clause
java.sql.SQLException: You can't specify target table 'test1' for update in FROM clause
去網(wǎng)上查過好像是說update以及delete操作沒辦法跟查詢操作一起做的,我看過有的更新的跟查詢的一起做的好像是給查出來的那部分起個(gè)別名,然后進(jìn)行更新就可以了,但是刪除這個(gè)我起了別名也不對,不知道是我寫錯(cuò)還是不行,我就跳過這個(gè)方法了。
我用的方法是:先查出數(shù)據(jù)庫中的重復(fù)記錄的數(shù)據(jù)中的一條,這個(gè)不難,很簡單的,sql語句如下:
select * from test1 where name in (select ?name from test1 ?group ?by ?name ? having ?count(name) 1)
and id in (select min(id) from ?test1 ?group by name ?having count(name)1)
結(jié)果如下:
id |name |phont |
---|--------|-------|
1 |name22 |123 |
3 |name222 |123 |
5 |name2 |123123 |
8 |123 |123123 |
11 |name1 |123123 |
13 |111 |1231 |
14 |112 |1232 |
這些都是不重復(fù)的,換句話說都是要保留的,不被刪掉的,而其余與這些結(jié)果中name相同的應(yīng)該被刪掉。
也就是說將上邊那個(gè)sql語句id后邊加一個(gè)not ,查出來的結(jié)果就是要?jiǎng)h掉的:結(jié)果如下
id |name |phont |
---|--------|-------|
2 |name22 |123 |
4 |name222 |123 |
6 |name2 |123123 |
7 |name2 |NULL |
9 |123 |123123 |
10 |123 |123123 |
12 |name1 |123123 |
15 |111 |1233 |
16 |112 |1234 |
17 |111 |1235 |
18 |112 |1236 |
我把這些需要?jiǎng)h掉的存到另外一個(gè)表里,然后我新建一個(gè)test2表,結(jié)構(gòu)復(fù)制test1的結(jié)構(gòu)就好了
1 CREATE TABLE `test2` (2 ? `id` int(11) NOT NULL AUTO_INCREMENT,3 ? `name` varchar(50) DEFAULT NULL,4 ? `phont` varchar(50) DEFAULT NULL,5 ? PRIMARY KEY (`id`)6 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
然后插入語句是:
1 insert into test2(2 select * from test.test1 where name in (select ?name from test.test1 ?group ?by ?name ? having ?count(name) 1)
3 and id not in (select min(id) from ?test.test1 ?group by name ?having count(name)1)
4 )
然后test2的表里的數(shù)據(jù)就是下圖這樣的:
那接下來做的就是刪掉test1表里邊與test2表的id相同的數(shù)據(jù)。
1 delete a.* from test1 a, test2 b where a.id = b.id ;
這樣,test1里邊的數(shù)據(jù)就變成了:
這樣的結(jié)果就是完全不重復(fù)的,但是我還想要他們的id是連續(xù)的,而不是這樣的斷開的。
我的做法是將這個(gè)表的除掉id之外的所有字段查出插入到另外一個(gè)表test3中,當(dāng)然,test3要設(shè)置id為自增主鍵,但是不插入id,讓它自增,就連續(xù)了
當(dāng)然要新建表test3啦,不過把上邊新建的test2那個(gè)復(fù)制下來改名字為test3就好啦。
然后插入:
1 insert into test3(name, phont)2 (select name, phont from test2)
test3表里的結(jié)果就是:
這樣就可以把test3改成你想要的名字,然后刪掉test1和test2了,大功告成~
不過感覺還可以就是將已經(jīng)刪掉重復(fù)數(shù)據(jù)的表test1的數(shù)據(jù)全都導(dǎo)出來,一般的數(shù)據(jù)庫連接工具都有這樣的功能,導(dǎo)成sql格式的,然后新建一個(gè)表,比test1多增一個(gè)自增主鍵字段叫NewId字段,但是Id字段不能再自增了,然后將導(dǎo)成的sql文件導(dǎo)入,不過那個(gè)sql文件可能要編輯一下,改一下自增主鍵id變?yōu)槠胀ǖ淖侄问裁吹模缓蟮叫卤砹酥螅瑒h掉id字段,修改NewId為Id,應(yīng)該也可以,但是這個(gè)方法我沒試過,原先預(yù)想過要這么做但是沒有這么做,估計(jì)以后可以試試,但是感覺兩種的麻煩程度都差不多啊,但是如果將sql語句寫下來之后可能還是第一種方法比較快一點(diǎn)吧。
通常情況下,一個(gè)我們在做一個(gè)產(chǎn)品的時(shí)候,一開始可能由于設(shè)計(jì)考慮不周或者程序?qū)懙牟粔驀?yán)謹(jǐn),某個(gè)字段上的值產(chǎn)生重復(fù)了,但是又必須去掉,這個(gè)時(shí)候就稍微麻煩了一點(diǎn),直接加一個(gè) UNIQUE KEY 肯定是不行了,因?yàn)闀?huì)報(bào)錯(cuò)。
現(xiàn)在,我們來采用一種變通的辦法,不過可能會(huì)丟失一些數(shù)據(jù) :)
在這里,我們設(shè)定一個(gè)表,其結(jié)構(gòu)如下:
mysql desc `user`;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | char(10) | NO | | | |
| extra | char(10) | NO | | | |
+-------+------------------+------+-----+---------+----------------+
原來表中的數(shù)據(jù)假定有以下幾條:
mysql SELECT * FROM `user`;
+----+-------+--------+
| id | name | extra |
+----+-------+--------+
| 1 | user1 | user1 |
| 2 | user2 | user2 |
| 3 | user3 | user3 |
| 4 | user4 | user4 |
| 5 | user5 | user5 |
| 6 | user3 | user6 |
| 7 | user6 | user7 |
| 8 | user2 | user8 |
| 9 | USER2 | user9 |
| 10 | USER6 | user10 |
+----+-------+--------+
1、將原來的數(shù)據(jù)導(dǎo)出
mysqlSELECT * INTO OUTFILE '/tmp/user.txt' FROM `user`;
2、清空數(shù)據(jù)表
mysqlTRUNCATE TABLE `user`;
3、創(chuàng)建唯一索引,并且修改 `name` 字段的類型為 BINARY CHAR 區(qū)分大小寫
mysql ALTER TABLE `user` MODIFY `name` CHAR(10) BINARY NOT NULL DEFAULT '';
mysql ALTER TABLE `user` ADD UNIQUE KEY ( `name` );
現(xiàn)在來看看新的表結(jié)構(gòu):
mysql desc user;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | char(10) | NO | UNI | | |
| extra | char(10) | NO | | | |
+-------+------------------+------+-----+---------+----------------+
4、把數(shù)據(jù)導(dǎo)回去,在這里,有兩種選擇:新的重復(fù)記錄替換舊的記錄,只保留最新的記錄 或者是 新的記錄略過,只保留最舊的記錄
mysql LOAD DATA INFILE '/tmp/user.txt' REPLACE INTO TABLE `user`;
Query OK, 10 rows affected (0.00 sec)
Records: 8 Deleted: 2 Skipped: 0 Warnings: 0
mysql SELECT * FROM USER;
+----+-------+--------+
| id | name | extra |
+----+-------+--------+
| 1 | user1 | user1 |
| 8 | user2 | user8 |
| 6 | user3 | user6 |
| 4 | user4 | user4 |
| 5 | user5 | user5 |
| 7 | user6 | user7 |
| 9 | USER2 | user9 |
| 10 | USER6 | user10 |
+----+-------+--------+
上面是采用 REPLACE 的方式,可以看到,導(dǎo)入過程中刪掉了兩條數(shù)據(jù),結(jié)果驗(yàn)證確實(shí)是 新的重復(fù)記錄替換舊的記錄,只保留最新的記錄。
現(xiàn)在,來看看用 IGNORE 的方式:
mysql LOAD DATA INFILE '/tmp/user.txt' IGNORE INTO TABLE `user`;
Query OK, 6 rows affected (0.01 sec)
Records: 8 Deleted: 0 Skipped: 2 Warnings: 0
mysql SELECT * FROM USER;
+----+-------+--------+
| id | name | extra |
+----+-------+--------+
| 1 | user1 | user1 |
| 2 | user2 | user2 |
| 3 | user3 | user3 |
| 4 | user4 | user4 |
| 5 | user5 | user5 |
| 7 | user6 | user7 |
| 9 | USER2 | user9 |
| 10 | USER6 | user10 |
+----+-------+--------+
看到了吧,確實(shí)是 新的記錄略過,只保留最舊的記錄。
分享標(biāo)題:mysql怎么去重復(fù)數(shù)據(jù),mysql怎么查重復(fù)的數(shù)據(jù)
當(dāng)前地址:http://chinadenli.net/article31/dsichpd.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、全網(wǎng)營銷推廣、靜態(tài)網(wǎng)站、云服務(wù)器、做網(wǎng)站、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)