我需要DELETE为指定的sid复制行MySQL表。
如何使用SQL查询做到这一点?
DELETE (DUPLICATED TITLES) FROM table WHERE SID = "1"这样的东西,但我不知道该怎么做。
我需要DELETE为指定的sid复制行MySQL表。
如何使用SQL查询做到这一点?
DELETE (DUPLICATED TITLES) FROM table WHERE SID = "1"这样的东西,但我不知道该怎么做。
Answers:
这将删除重复项,而无需创建新表
ALTER IGNORE TABLE `table_name` ADD UNIQUE (title, SID)注意:仅当索引适合内存时才有效
ALTER IGNORE。
                    ALTER TABLE foo ENGINE MyISAM解决它,之后又换了引擎。
                    假设您有一个表格employee,其中包含以下列:
employee (first_name, last_name, start_date)为了删除具有重复first_name列的行:
delete
from employee using employee,
    employee e1
where employee.id > e1.id
    and employee.first_name = e1.first_name  employee针对一个索引匹配和>对一个索引的检查而对自身联接。SELECT MAX(ID) FROM t GROUP BY unique然后再JOIN匹配ID到完全匹配会更好MAX(ID)吗?
                    接下来,删除所有SID的重复项,而不仅仅是单个。
带临时表
CREATE TABLE table_temp AS
SELECT * FROM table GROUP BY title, SID;
DROP TABLE table;
RENAME TABLE table_temp TO table;由于temp_table是刚创建的,因此没有索引。删除重复项后,您需要重新创建它们。您可以使用以下命令检查表中的索引SHOW INDEXES IN table
没有临时表:
DELETE FROM `table` WHERE id IN (
  SELECT all_duplicates.id FROM (
    SELECT id FROM `table` WHERE (`title`, `SID`) IN (
      SELECT `title`, `SID` FROM `table` GROUP BY `title`, `SID` having count(*) > 1
    )
  ) AS all_duplicates 
  LEFT JOIN (
    SELECT id FROM `table` GROUP BY `title`, `SID` having count(*) > 1
  ) AS grouped_duplicates 
  ON all_duplicates.id = grouped_duplicates.id 
  WHERE grouped_duplicates.id IS NULL
)SELECT * FROM table GROUP BY title, SID;这完全取决于您对自己在做什么的了解。
                    创建表并插入一些行:
create table penguins(foo int, bar varchar(15), baz datetime);
insert into penguins values(1, 'skipper', now());
insert into penguins values(1, 'skipper', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(4, 'rico', now());
select * from penguins;
    +------+----------+---------------------+
    | foo  | bar      | baz                 |
    +------+----------+---------------------+
    |    1 | skipper  | 2014-08-25 14:21:54 |
    |    1 | skipper  | 2014-08-25 14:21:59 |
    |    3 | kowalski | 2014-08-25 14:22:09 |
    |    3 | kowalski | 2014-08-25 14:22:13 |
    |    3 | kowalski | 2014-08-25 14:22:15 |
    |    4 | rico     | 2014-08-25 14:22:22 |
    +------+----------+---------------------+
6 rows in set (0.00 sec)删除重复项:
delete a
    from penguins a
    left join(
    select max(baz) maxtimestamp, foo, bar
    from penguins
    group by foo, bar) b
    on a.baz = maxtimestamp and
    a.foo = b.foo and
    a.bar = b.bar
    where b.maxtimestamp IS NULL;
Query OK, 3 rows affected (0.01 sec)
select * from penguins;
+------+----------+---------------------+
| foo  | bar      | baz                 |
+------+----------+---------------------+
|    1 | skipper  | 2014-08-25 14:21:59 |
|    3 | kowalski | 2014-08-25 14:22:15 |
|    4 | rico     | 2014-08-25 14:22:22 |
+------+----------+---------------------+
3 rows in set (0.00 sec)完成后,将删除重复的行,并保留时间戳的最后一行。
您没有timestamp或唯一的索引列作为排序依据?您正处于堕落状态。您必须执行其他步骤才能删除重复的行。
创建企鹅表并添加一些行
create table penguins(foo int, bar varchar(15)); 
insert into penguins values(1, 'skipper'); 
insert into penguins values(1, 'skipper'); 
insert into penguins values(3, 'kowalski'); 
insert into penguins values(3, 'kowalski'); 
insert into penguins values(3, 'kowalski'); 
insert into penguins values(4, 'rico'); 
select * from penguins; 
    # +------+----------+ 
    # | foo  | bar      | 
    # +------+----------+ 
    # |    1 | skipper  | 
    # |    1 | skipper  | 
    # |    3 | kowalski | 
    # |    3 | kowalski | 
    # |    3 | kowalski | 
    # |    4 | rico     | 
    # +------+----------+ 复制第一个表并复制到该表中。
drop table if exists penguins_copy; 
create table penguins_copy as ( SELECT foo, bar FROM penguins );  
#add an autoincrementing primary key: 
ALTER TABLE penguins_copy ADD moo int AUTO_INCREMENT PRIMARY KEY first; 
select * from penguins_copy; 
    # +-----+------+----------+ 
    # | moo | foo  | bar      | 
    # +-----+------+----------+ 
    # |   1 |    1 | skipper  | 
    # |   2 |    1 | skipper  | 
    # |   3 |    3 | kowalski | 
    # |   4 |    3 | kowalski | 
    # |   5 |    3 | kowalski | 
    # |   6 |    4 | rico     | 
    # +-----+------+----------+ 最大合计根据新的moo指数进行操作:
delete a from penguins_copy a left join( 
    select max(moo) myindex, foo, bar 
    from penguins_copy 
    group by foo, bar) b 
    on a.moo = b.myindex and 
    a.foo = b.foo and 
    a.bar = b.bar 
    where b.myindex IS NULL; 
#drop the extra column on the copied table 
alter table penguins_copy drop moo; 
select * from penguins_copy; 
#drop the first table and put the copy table back: 
drop table penguins; 
create table penguins select * from penguins_copy; 观察和清理
drop table penguins_copy; 
select * from penguins;
+------+----------+ 
| foo  | bar      | 
+------+----------+ 
|    1 | skipper  | 
|    3 | kowalski | 
|    4 | rico     | 
+------+----------+ 
    Elapsed: 1458.359 milliseconds 那条大的SQL delete语句在做什么?
别名为“ a”的表企鹅在称为别名“ b”的表企鹅的子集上保持连接。右表“ b”是一个子集,可找到由列foo和bar分组的最大时间戳[或max moo]。这与左表“ a”匹配。左侧的(foo,bar,baz)表格中的每一行。右侧子集“ b”具有(maxtimestamp,foo,bar),仅在最大的那一个上与左侧匹配。
非最大的每一行的maxtimestamp值为NULL。筛选掉这些NULL行,您将获得一组由foo和bar分组的所有行,这些行不是最新的时间戳baz。删除那些。
运行此表之前,请对其进行备份。
防止此问题在此表上再次发生:
如果您能做到这一点,那么它就会扑灭您的“重复行”。大。现在,在表上(这两列上)定义一个新的复合唯一键,以防止首先添加更多重复项。
就像一个好的免疫系统一样,插入时也不应该将坏行插入表中。后来,所有添加重复项的程序都会广播他们的抗议,而当您修复它们时,此问题就再也不会出现。
ID列,则该ON子句只需要与该ID列匹配,就不需要别的了。
                    我自己在一个巨大的数据库上遇到这个问题之后,对其他任何答案的性能都没有完全印象。我只想保留最新的重复行,并删除其余的行。
在没有临时表的单查询语句中,这对我来说效果最好,
DELETE e.*
FROM employee e
WHERE id IN
 (SELECT id
   FROM (SELECT MIN(id) as id
          FROM employee e2
          GROUP BY first_name, last_name
          HAVING COUNT(*) > 1) x);唯一的警告是,我必须多次运行查询,但是即使如此,我发现它对我来说比其他选项更好。
这似乎总是为我工作:
CREATE TABLE NoDupeTable LIKE DupeTable; 
INSERT NoDupeTable SELECT * FROM DupeTable group by CommonField1,CommonFieldN;这样,每个重复项和其余非重复记录中的ID最低。
我还采取了以下措施,以使删除后不再出现重复问题:
CREATE TABLE NoDupeTable LIKE DupeTable; 
Alter table NoDupeTable Add Unique `Unique` (CommonField1,CommonField2);
INSERT IGNORE NoDupeTable SELECT * FROM DupeTable;换句话说,我创建了第一个表的副本,在我不希望重复的字段上添加了唯一索引,然后执行了一个Insert IGNORE具有不会像平常一样失败的优点Insert第一次尝试添加基于两个字段的重复记录,而忽略任何此类记录。
向前移动,就不可能基于这两个字段创建任何重复的记录。
ORDER BY,SELECT以确保实际将哪个记录转交给NoDupeTable?
                    ORDER by ID Asc可以,所以我还是要编辑我的答案。
                    Select Max(ID),然后做,Order by Max(ID)但所有要做的就是颠倒插入的顺序。要获取最高的ID,我相信需要更复杂的选择联接,无论您如何在上方订购,都将从较低的ID获取字段值。
                    MAX(ID)或者MIN(ID)和列名,而不是*在SELECT FROM DupeTable虽然,否则你会刚刚得到的一个ID的随机。实际上,许多SQL甚至MySQL严格要求在GROUP BY子句中未指定的每一列上调用聚合函数。
                    ID,First,Last,Notes和记录的记录1,Bob,Smith,NULL,2,Bob,Smith,Arrears然后执行a SELECT *Max(ID), First,Last,Notes FROM DupeTable group by First,Last都将返回相同的记录1,但ID不同。Max(ID)将返回,2,Bob,Smith,NULL而Min(ID)将返回1,Bob,Smith,NULL。我相信要获得笔记中带有“欠款”的第二张唱片,需要参加。
                    这是一个简单的答案:
delete a from target_table a left JOIN (select max(id_field) as id, field_being_repeated  
    from target_table GROUP BY field_being_repeated) b 
    on a.field_being_repeated = b.field_being_repeated
      and a.id_field = b.id_field
    where b.id_field is null;and a.id_field = b.id
                    LEFT JOIN以b只需要比较b.id= a.id_field假设field_id是一个独特的自动递增ID。所以a.field_being_repeated = b.field_being_repeated是无关紧要的。(也b.id_field不会在此查询它的存在b.id。
                    delete p from 
product p
inner join (
    select max(id) as id, url from product 
    group by url 
    having count(*) > 1
) unik on unik.url = p.url and unik.id != p.id;我在上面找到了Werner的解决方案是最方便的,因为无论主键是否存在,它都能工作,不会与表混淆,使用面向未来的纯SQL,这是很容易理解的。
正如我在评论中指出的那样,该解决方案尚未得到适当的解释。所以这是我的,基于此。
1)添加一个新的布尔列
alter table mytable add tokeep boolean;2)在重复的列和新列上添加约束
alter table mytable add constraint preventdupe unique (mycol1, mycol2, tokeep);3)将布尔列设置为true。由于新的限制,这将仅在重复的行之一上成功
update ignore mytable set tokeep = true;4)删除未标记为保留的行
delete from mytable where tokeep is null;5)删除添加的列
alter table mytable drop tokeep;我建议您保留添加的约束,以便将来避免新的重复项。
此过程将删除表中的所有重复项(包括多个),并保留最后一个重复项。这是检索每个组中的最后一条记录的扩展
希望这对某人有用。
DROP TABLE IF EXISTS UniqueIDs;
CREATE Temporary table UniqueIDs (id Int(11));
INSERT INTO UniqueIDs
    (SELECT T1.ID FROM Table T1 LEFT JOIN Table T2 ON
    (T1.Field1 = T2.Field1 AND T1.Field2 = T2.Field2 #Comparison Fields 
    AND T1.ID < T2.ID)
    WHERE T2.ID IS NULL);
DELETE FROM Table WHERE id NOT IN (SELECT ID FROM UniqueIDs);另一种简单的方法...使用UPDATE IGNORE:
U必须在一个或多个列上使用索引(类型索引)。创建一个新的临时参考列(不属于索引)。在此列中,您可以通过用ignore子句更新唯一性来标记唯一性。一步步:
添加一个临时参考列以标记唯一性:
ALTER TABLE `yourtable` ADD `unique` VARCHAR(3) NOT NULL AFTER `lastcolname`;=>这会将一列添加到您的表中。
更新表,尝试将所有内容标记为唯一,但忽略由于重复的密钥问题而导致的可能的错误(将跳过记录):
UPDATE IGNORE `yourtable` SET `unique` = 'Yes' WHERE 1;=>您会发现重复记录不会被标记为唯一='是',换句话说,每组重复记录中只有一个会被标记为唯一。
删除所有不唯一的内容:
DELETE * FROM `yourtable` WHERE `unique` <> 'Yes';=>这将删除所有重复的记录。
放下列...
ALTER TABLE `yourtable` DROP `unique`;unique必须将列与当前正在复制的列一起添加到唯一约束中,否则整个事情将不起作用,因为SET unique='Yes'将永远不会失败。
                    unique是一个mysql关键字。因此,它必须具有反引号(如已正确显示)。在该列中使用另一个单词可能会更方便。
                    删除MySQL表上的重复项是一个普遍的问题,通常伴随特定的需求。如果有人感兴趣,这里(在MySQL中删除重复的行)我将解释如何使用临时表以可靠,快速的方式删除MySQL重复项,这对于处理大数据源也是有效的(针对不同用例的示例)。
对于Ali,您可以运行以下命令:
-- create a new temporary table
CREATE TABLE tmp_table1 LIKE table1;
-- add a unique constraint    
ALTER TABLE tmp_table1 ADD UNIQUE(sid, title);
-- scan over the table to insert entries
INSERT IGNORE INTO tmp_table1 SELECT * FROM table1 ORDER BY sid;
-- rename tables
RENAME TABLE table1 TO backup_table1, tmp_table1 TO table1;喜欢@eric的答案,但是如果您有一个很大的表,它似乎不起作用(The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay尝试运行该表时会得到提示)。因此,我将联接查询限制为仅考虑重复的行,最后得到:
DELETE a FROM penguins a
    LEFT JOIN (SELECT COUNT(baz) AS num, MIN(baz) AS keepBaz, foo
        FROM penguins
        GROUP BY deviceId HAVING num > 1) b
        ON a.baz != b.keepBaz
        AND a.foo = b.foo
    WHERE b.foo IS NOT NULL在这种情况下,WHERE子句允许MySQL忽略没有重复项的任何行,并且如果这是重复项的第一个实例,也将忽略它,因此仅后续的重复项将被忽略。更改MIN(baz)为MAX(baz)保留最后一个实例而不是第一个实例。
这适用于大表:
 CREATE Temporary table duplicates AS select max(id) as id, url from links group by url having count(*) > 1;
 DELETE l from links l inner join duplicates ld on ld.id = l.id WHERE ld.id IS NOT NULL;要删除最早的变化max(id)来min(id)
这将使该列成column_name为主键,同时忽略所有错误。因此它将删除具有重复值的行column_name。
ALTER IGNORE TABLE `table_name` ADD PRIMARY KEY (`column_name`);DELETE T2
FROM   table_name T1
JOIN   same_table_name T2 ON (T1.title = T2.title AND T1.ID <> T2.ID)从表中删除重复数据时,只有几个基本步骤:
这是完整的教程:https : //blog.teamsql.io/deleting-duplicate-data-3541485b3473