MySQL如何合并重复记录
Posted
技术标签:
【中文标题】MySQL如何合并重复记录【英文标题】:How to merge duplicate records in MySQL 【发布时间】:2020-01-07 02:30:00 【问题描述】:我有 1100 万行的 post_view_counters 表。
id post_id start_date end_date views
_________________________________________________
1 55 XXXX YYYY 90
2 55 XXXX YYYY 1
3 55 XXXX YYYY 1
由于某种原因(后端中的错误)存在重复记录,这些记录已经修复。 我需要合并具有相同 post_id、start_date 和 end_date 的所有行视图 更新表格后的结果应该是这样的
id post_id start_date end_date views
_________________________________________________
1 55 XXXX YYYY 92
【问题讨论】:
表是 MyISAM 还是 InnoDB ?表上是否定义了任何索引?您是否要直接在生产中进行此更改(例如当您的应用程序实际使用表时)?由于是一张大桌子,答案会因影响生产的严重程度而异。 start_date end_date 对于所有行都应该相同 所以您想删除重复项,以便表格上只剩下一行,但查看次数正确 @RiggsFolly 是的,只有一行更新了视图 【参考方案1】:首先,您必须为每个post_id, start_date, end_date
更新具有最小id
的行:
update tablename t inner join (
select sum(views) views, min(id) id from tablename
group by post_id, start_date, end_date
) tt
on tt.id = t.id
set t.views = tt.views;
然后删除所有其他id,只保留最小id
:
delete t
from tablename t inner join tablename tt
on tt.post_id = t.post_id
and tt.start_date = t.start_date and tt.end_date = t.end_date
and t.id > tt.id;
由于这是一个大表,因此需要适当的索引以使进程尽可能快地运行。 请参阅demo。 对于此表:
CREATE TABLE tablename (
`id` INTEGER,
`post_id` INTEGER,
`start_date` VARCHAR(4),
`end_date` VARCHAR(4),
`views` INTEGER
);
INSERT INTO tablename
(`id`, `post_id`, `start_date`, `end_date`, `views`)
VALUES
('1', '55', 'XXXX', 'YYYY', '90'),
('2', '55', 'XXXX', 'YYYY', '1'),
('3', '55', 'XXXX', 'YYYY', '1'),
('4', '65', 'AAAA', 'BBBB', '10'),
('5', '65', 'AAAA', 'BBBB', '2'),
('6', '65', 'AXXX', 'BYYY', '100'),
('7', '65', 'AXXX', 'BYYY', '200'),
('8', '75', 'CCCC', 'CCCC', '1');
结果:
| id | post_id | start_date | end_date | views |
| --- | ------- | ---------- | -------- | ----- |
| 1 | 55 | XXXX | YYYY | 92 |
| 4 | 65 | AAAA | BBBB | 12 |
| 6 | 65 | AXXX | BYYY | 300 |
| 8 | 75 | CCCC | CCCC | 1 |
【讨论】:
【参考方案2】:我会采取安全的方法:
首先,新建一个表——
CREATE TABLE post_view_counters_new LIKE post_view_counters;
然后将数据插入到新表中——(@scaisEdge 的语法)
INSERT INTO post_view_counters_new
SELECT MIN(id) id, post_id , start_date , end_date , SUM( views) views
FROM post_view_counters
GROUP BY post_id , start_date , end_date;
之后,比较新表和旧表的数据。满意后,将旧表重命名为“post_view_counters_old”,并将“post_view_counters_new”重命名为“post_view_counters”。因此,如果您在新表中缺少任何内容,您仍然可以参考旧表。
【讨论】:
好答案+1;但同样是直接delete
更好还是create .. insert
方法;从性能的角度来看,这完全取决于实际存在多少重复行。【参考方案3】:
你可以试试下面-
select min(id),post_id, start_date , end_date,sum(views)
from tablename
group by post_id, start_date, end_date
【讨论】:
伙计们,请参阅comment 并在下方回答【参考方案4】:对于相同的 post_id , start_date , end_date 你可以使用聚合函数 作为 min(id) , sum(view ) 和 group by
select min(id) id, post_id , start_date , end_date , sum( views) views
from my_table
group by post_id , start_date , end_date
【讨论】:
我不需要 select ,我需要在 table 中更新所有行 各位,见comment并在下方回答以上是关于MySQL如何合并重复记录的主要内容,如果未能解决你的问题,请参考以下文章