Php 当列具有相同的条目时,删除双行

Php 当列具有相同的条目时,删除双行,php,mysql,sql,delete-row,sql-delete,Php,Mysql,Sql,Delete Row,Sql Delete,我有一个带有自动递增列id的数据库表test_表,当3个特定列a、B、C具有相同的条目时,我希望删除所有两个或多个条目 id column_A column_B column_C ------------------------------------------------ 1 ooo aaa uuu 2 ooo aaa uuu 3 ttt

我有一个带有自动递增列id的数据库表test_表,当3个特定列a、B、C具有相同的条目时,我希望删除所有两个或多个条目

    id    column_A    column_B    column_C
------------------------------------------------
    1     ooo         aaa         uuu
    2     ooo         aaa         uuu
    3     ttt         ppp         uuu
    4     ooo         aaa         uuu
    5     iii         kkk         ccc
在本例中,应在执行删除查询后删除id为2和4的行


认为。

作为一种快速的可能性,我从以下方面借用了这一点:

步骤1:将非重复的唯一元组移动到临时表中

CREATE TABLE new_table AS
SELECT * FROM old_table WHERE 1 GROUP BY [COLUMN TO remove duplicates BY];
步骤2:删除旧表

DROP TABLE old_table;
步骤3:将新的_表重命名为旧的_表的名称

RENAME TABLE new_table TO old_table;

然后,您可以编辑新表,使A列成为主键,不再发生重复。

作为一种快速的可能性,我借用了以下内容:

DELETE FROM tbl
WHERE `id` NOT IN ( SELECT * FROM (
                                SELECT MIN(`id`) 
                                FROM tbl
                                GROUP BY `column_A`
                                       , `column_B`
                                       , `column_C` 
                              ) x
              )
步骤1:将非重复的唯一元组移动到临时表中

CREATE TABLE new_table AS
SELECT * FROM old_table WHERE 1 GROUP BY [COLUMN TO remove duplicates BY];
步骤2:删除旧表

DROP TABLE old_table;
步骤3:将新的_表重命名为旧的_表的名称

RENAME TABLE new_table TO old_table;
然后,您可以编辑新表,使列A成为主键,不再发生重复

DELETE FROM tbl
WHERE `id` NOT IN ( SELECT * FROM (
                                SELECT MIN(`id`) 
                                FROM tbl
                                GROUP BY `column_A`
                                       , `column_B`
                                       , `column_C` 
                              ) x
              )

您可以在删除查询中使用自联接,联接中的子查询将联接重复的行,条件t.id>tt.id将保留id为的最小记录,其他重复项将被删除

delete t.* from t
join (
select * from t 
group by `column_A`, `column_B`, `column_C`
having count(*) > 1
) tt 
  on(t.`column_A` = tt.`column_A`
          AND t.`column_B` = tt.`column_B`
          AND t.`column_C` = tt.`column_C` 
         AND t.id > tt.id)
我已经添加了第五行的一个副本来测试它


您可以在删除查询中使用自联接,联接中的子查询将联接重复的行,条件t.id>tt.id将保留id为的最小记录,其他重复项将被删除

delete t.* from t
join (
select * from t 
group by `column_A`, `column_B`, `column_C`
having count(*) > 1
) tt 
  on(t.`column_A` = tt.`column_A`
          AND t.`column_B` = tt.`column_B`
          AND t.`column_C` = tt.`column_C` 
         AND t.id > tt.id)
我已经添加了第五行的一个副本来测试它


你是说第一个回答总是正确的,应该保留下来吗?如果总是这样,您能将列a设置为您的主键,而主键本质上不允许重复吗?不是修复,而是最佳实践…@Silvertiger:实际上我正在清理一个现有的数据库。哪一个自动递增键离开并不重要,重要的是删除了两倍的条目,并保留了其中一行。您是说第一个响应始终是应该保留的正确响应吗?如果总是这样,您能将列a设置为您的主键,而主键本质上不允许重复吗?不是修复,而是最佳实践…@Silvertiger:实际上我正在清理一个现有的数据库。保留哪个自动递增键并不重要,重要的是删除了两倍的条目并保留了其中一行。感谢您将fiddle放在一起。通过此查询,我得到一个SQL错误1205-超过了锁定等待超时;尝试重新启动事务。使用InnoDB表。此查询是否比Notulyses提供的查询占用更多资源?感谢您将fiddle放在一起。通过此查询,我得到一个SQL错误1205-超过锁等待超时;尝试重新启动事务。使用InnoDB表。此查询是否比Notulyses提供的查询占用更多的资源?@lickmycode:因为在更新/插入/删除查询中不能在WHERE子句中使用永久表,所以这里的x将其表示为临时表。@lickmycode:因为在更新/插入/删除查询中不能在WHERE子句中使用永久表,所以这里的x表示为一个临时表。看起来LinkedIn链接中的Richa Tayal人实际上从中得到了答案。看起来LinkedIn链接中的Richa Tayal人实际上从中得到了答案。