mysql查詢重複行且按某種條件保留資料
總結mysql查詢重複行且按一定條件保留所重複的資料中的一條記錄:
第一種情況,判斷保留記錄的條件是主鍵或是唯一值
--
-- 表的結構 `test`
--
CREATE TABLE IF NOT EXISTS `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(16) NOT NULL,
`phone` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- 匯出表中的資料 `test`
--
INSERT INTO `test` (`id`, `name`, `phone`) VALUES
(1, 'a', 1234),
(2, 'a', 3333),
(3, 'b', 555),
(4, 'b', 6773),
(5, 'a', 743),
(6, 'c', 95434);
查詢一下,
SELECT * FROM `test` group by name
得到
id name phone
1 a 1234
3 b 555
6 c 95434
但我們想得到id最大的name怎麼辦?
SELECT max(id),id,name,phone FROM test group by name
得到
max(id) id name phone
5 1 a 1234
4 3 b 555
6 6 c 95434
可以看到,雖然每個name的最大id得到了,但是,其他資料依然是每個name的第一行,此處需要注意
用子查詢
select * from (select * from test order by id desc) t group by name
id name phone
5 a 743
4 b 6773
6 c 95434
這就是我們想要的結果了,記錄看起來在執行group的時候,會按name進行排序(有待確定group和order的關係)。但是,這種作法在行數非常多的情況下,相當於把整個表複製了一次,效率比較低,在對31144條資料進行測試的時候,用時58.437s
那用這種子查詢 select * from test t where id in (select max(id) from test group by name)
得到
id name phone
4 b 6773
5 a 743
6 c 95434
然而,這種子查詢因為用了in,在對31144條資料進行測試的時候,效率更低,用時達15萬s,所以當資料量大時,最好不要用此查詢。
第二種情況,判斷保留記錄的條件是重複值
--
-- 表的結構 `message`
--
CREATE TABLE `message` (
`pid` int(11) NOT NULL,
`nums` int(11) default NULL,
`source_type` char(255) default NULL,
`source_id` int(11) default NULL,
`source_name` char(255) default NULL,
`columnId` int(11) default NULL,
`category` char(255) default NULL,
`cp_id` char(255) default NULL,
` company` char(255) default NULL,
`online` char(255) default NULL,
`last_modify_time` char(255) default NULL,
`operator_system` char(255) default NULL,
`java_platform` char(255) default NULL,
`screen_length` int(11) default NULL,
`screen_width` int(11) default NULL,
PRIMARY KEY (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
資料按以下9個欄位判定重複,且按欄位的先後順序進行分組和排序:
online,source_type,
columnId,source_name,category,operator_system,java_platform,screen_length,screen_width
以上條件重複的記錄按欄位last_modify_time判定,保留時間最早的記錄,刪除其他重複的資料
select * from (select * from message21 order by last_modify_time ) t group by online,source_type,
columnId,source_name,category,operator_system,java_platform,screen_length,screen_width
同樣,對於排序,實際上group的時候已經達到了排序的結果。