限制在没有PK的表中删除的行数

时间:2016-06-27 18:15:01

标签: mysql sql

我正在开发一个系统,由于某种原因,有人创建了一个“类别”表而没有PK类别的ID。我刚刚发现,现在该表有所有行的副本,并导致我的一些查询出现问题。

我的问题是:有没有办法删除重复的行,将“原件”留在表中,而不依赖索引?

这是SELECT * FROM categories

+-----------+-------------+
| categoria | descripcion |
+-----------+-------------+
|         1 | Int.Cons.   |
|         2 | Delegado    |
|         3 | Personal    |
|         4 | Comun       |
|         5 | Proveedor   |
|         6 | Menor/Inc   |
|        11 | N/Categoria |
|         1 | Int.Cons.   |
|         2 | Delegado    |
|         3 | Personal    |
|         4 | Comun       |
|         5 | Proveedor   |
|         6 | Menor/Inc   |
|        11 | N/Categoria |
+-----------+-------------+

桌子上没有定义索引。

4 个答案:

答案 0 :(得分:1)

您可以通过多种方式删除记录。我可能会建议使用临时表,然后正确地重新填充表:

create temporary table temp_categories as 
    select c.id, c.descripcion
    from categories c
    group by c.id;

truncate table categories;

insert into categories(id, descripcion)
    select id, descripcion
    from temp_categories;


alter table add constraint primary key (id);
alter table add constraint unq_categories_descripcion unique (descripcion);

答案 1 :(得分:1)

如果/因为创建新表不是一个选项,你可以运行这样的东西;但是你需要反复运行它,直到所有的重复都消失了。

DELETE FROM categories 
WHERE (categoria, descripcion) IN (
   SELECT categoria, descripcion 
   FROM categories 
   GROUP BY categoria, descripcion 
   HAVING COUNT(*) > 1
)
LIMIT 1
;

编辑:实际上,这应该具有临时表解决方案的好处而没有风险(因为真正的临时表是基于会话/连接的,如果连接失败,则会丢失数据)。 / p>

INSERT INTO categories (categoria, descripcion)
SELECT DISTINCT categoria, CONCAT('NEWCOPY---', descripcion)
FROM categories
;

DELETE FROM categories
WHERE descripcion NOT LIKE 'NEWCOPY---%'
;

UPDATE categories
SET descripcion = REPLACE(descripcion, 'NEWCOPY---', '')
;

显然,'NEWCOPY ---'可以/应该用表格中没有的前缀替换。

答案 2 :(得分:0)

在这个示例中,您可以轻松地完成此任务:

 CREATE TABLE xyz AS SELECT DISTINCT FROM categories;
 DROP TABLE categories;
 ALTER TABLE xyz RENAME categories;
 CREATE UNIQUE INDEX idx_nn_c_1 ON categories(id);

(在运行之前检查SQL,否则你将在DROP行丢失一个表)

答案 3 :(得分:0)

测试这个

sbt updateClassifiers