如何合并 MySQL 中的重复记录
How to merge duplicate records in MySQL
我有 post_view_counters table 有 1100 万行。
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 的所有行视图
更新后结果应该是这样 table
id post_id start_date end_date views
_________________________________________________
1 55 XXXX YYYY 92
对于相同的 post_id , start_date , end_date 你可以使用聚合函数
作为 min(id) 、 sum(view ) 和分组
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 min(id),post_id, start_date , end_date,sum(views)
from tablename
group by post_id, start_date, end_date
我会采取安全的方法:
首先,创建一个新的 table -
CREATE TABLE post_view_counters_new LIKE post_view_counters;
然后将数据插入到新的table-(@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;
之后,比较新table和旧table之间的数据。满意后,将旧的 table 重命名为 'post_view_counters_old' 并将 'post_view_counters_new' 重命名为 'post_view_counters'。因此,如果您在新 table 中遗漏了任何内容,您仍然可以参考旧 table.
首先,您必须为每个 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;
由于这是一个很大的 table,因此需要适当的索引以使过程 运行 尽可能快。
见 demo.
为此 table:
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 |
我有 post_view_counters table 有 1100 万行。
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 的所有行视图 更新后结果应该是这样 table
id post_id start_date end_date views
_________________________________________________
1 55 XXXX YYYY 92
对于相同的 post_id , start_date , end_date 你可以使用聚合函数 作为 min(id) 、 sum(view ) 和分组
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 min(id),post_id, start_date , end_date,sum(views)
from tablename
group by post_id, start_date, end_date
我会采取安全的方法:
首先,创建一个新的 table -
CREATE TABLE post_view_counters_new LIKE post_view_counters;
然后将数据插入到新的table-(@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;
之后,比较新table和旧table之间的数据。满意后,将旧的 table 重命名为 'post_view_counters_old' 并将 'post_view_counters_new' 重命名为 'post_view_counters'。因此,如果您在新 table 中遗漏了任何内容,您仍然可以参考旧 table.
首先,您必须为每个 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;
由于这是一个很大的 table,因此需要适当的索引以使过程 运行 尽可能快。
见 demo.
为此 table:
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 |