1. 程式人生 > >mysql查詢重複行且按某種條件保留資料

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的時候已經達到了排序的結果。