我正在开发一个系统,由于某种原因,有人创建了一个“类别”表而没有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 |
+-----------+-------------+
桌子上没有定义索引。
答案 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