如何在MySQL中合并重复记录

时间:2019-09-04 08:19:28

标签: php mysql large-data

我的post_view_counters表有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 开始日期结束日期的行视图 更新表后的结果应该是这样的

id    post_id    start_date    end_date    views
_________________________________________________
1       55          XXXX         YYYY        92

4 个答案:

答案 0 :(得分:3)

我会采取安全的方法:

首先,创建一个新表-

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 :(得分:0)

对于相同的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

答案 2 :(得分:0)

您可以在下面尝试-

select min(id),post_id,    start_date ,   end_date,sum(views)
from tablename
group by post_id, start_date, end_date

答案 3 :(得分:0)

首先,您必须为每个id用最小post_id, start_date, end_date更新行:

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     |