【问题标题】:How to delete duplicate rows in this case? [duplicate]在这种情况下如何删除重复的行? [复制]
【发布时间】:2013-04-23 09:13:47
【问题描述】:
|  id  |        name        |              date           |     points   |
|  10  |        Paul        |     2013-04-29 10:15:03     |       2      |
|  11  |       Joseph       |     2013-04-29 10:50:17     |       0      |
|  12  |       Joseph       |     2013-04-29 11:23:18     |       10     |
|  13  |        Bill        |     2013-04-29 11:27:10     |       8      |
|  14  |        Paul        |     2013-04-29 11:41:38     |       5      |
|  15  |       Joseph       |     2013-04-29 11:43:15     |       0      |
|  16  |       Joseph       |     2013-04-29 11:47:30     |       0      |
|  17  |       Joseph       |     2013-04-29 12:51:38     |       0      |
|  18  |       Joseph       |     2013-04-29 12:53:58     |       10     |
|  19  |        Bill        |     2013-04-29 13:17:10     |       8      |
|  20  |       Joseph       |     2013-04-29 13:21:38     |       7      |

只有寄存器 16 和 17 必须删除。

我需要的是,每次有来自同一用户的 0 序列时,都删除相同的序列,除了第一个 0,在本例中为 id 号 15。

【问题讨论】:

  • ID 总是递增的吗?

标签: mysql


【解决方案1】:

假设date字段总是递增的,你可以按照下一个过程进行

  1. 跟踪重复记录和这些记录的最短日期
  2. 删除日期值大于最小日期的所有记录。

代码示例:

第 1 步:

select name, points, count(id) as rowCount, min(id) as minId, min(`date`) as minDate
from yourTable
where points = 0
group by name
having count(id)>1

第 2 步:

delete from yourTable
where id in (
    select id
    from yourTable
    inner join (
            select name, points, min(id) as minId, count(id) as rowCount, min(`date`) as minDate
            from yourTable
            where points = 0
            group by name
            having count(id) > 1
        ) as a on yourTable.name = a.name and yourTable.id > a.minId
    )
and points = 0;

希望对你有帮助


我认为使用临时表来获取要删除的 id 可能很有用:

-- Step 1: Create a temporary table with the names of the people you want to remove
drop table if exists temp_dup_names;
create temporary table temp_dup_names
    select name, points, min(id) as minId, count(id) as rowCount, min(`date`) as minDate
    from yourTable
    where points = 0
    group by name
    having count(id) > 1;
alter table temp_dup_names
    add index idx_name(name),
    add unique index idx_id(minId);

-- Step 2: Create a temporary table with the ids you want to delete
drop table if exists temp_ids_to_delete;
create temporary table temp_ids_to_delete
    select distinct a.id
    from yourTable as a
    inner join temp_dup_names as b on a.name=b.name and a.id > b.minId
    where points = 0;
alter table temp_ids_to_delete
    add unique index idx_id(id);

-- Step 3: Delete the rows
delete from yourTable
where id in (select id from temp_ids_to_delete);
-- If MySQL is configured in 'safe mode', you may need to add this 
-- to the where condition:
-- and id > 0;

【讨论】:

  • 我不明白为什么,但它不起作用。删除了很多记录,但还是留下了很多同一个用户0,依次类推。
  • iddate 字段都是增量的吗? (即更大的id 值与更大的date 值配对)。我已经编辑了帖子以显示使用临时表的分步解决方案。检查步骤 2:临时表应该有您要删除的 ID。如果没有正确的 Id,则必须再次检查第 1 步
  • 是的,id 和 date 是递增的
  • @Guttemberg 好的。尝试第二版解决方案的步骤 1 和 2,并检查 temp_ids_to_delete 表 (select * from temp_ids_to_delete) 中的 Id。您要删除的行的 ID 应该在那里。
  • @Guttemberg 我在 SQL Fiddle 上尝试了这个过程,我发现要删除的行(根据您帖子中的数据)是 ids 15、16 和 17,因为那些是满足条件的重复 ID... ID 为 11 的行是 Joseph 得分为 0 的第一个行... 如果您需要跟踪“序列”,那么我建议您使用高级编程语言来跟踪您需要删除的记录。顺便说一句,我修改了查询以仅过滤 0 分记录
猜你喜欢
  • 2015-05-19
  • 2014-03-22
  • 2013-04-11
  • 1970-01-01
  • 2017-03-17
  • 2013-07-17
  • 2018-12-16
  • 2016-11-15
  • 1970-01-01
相关资源
最近更新 更多