Mysql 限制表中无主键删除的行数
我在一个系统上工作,由于某种原因,有人创建了一个“categories”表,但没有PK'ing该类别的ID。我刚刚发现,现在该表有一个所有行的副本,并导致我的一些查询出现问题 我的问题是:有没有一种方法可以删除重复的行,将“原始”保留在表中,而不依赖于索引 以下是Mysql 限制表中无主键删除的行数,mysql,sql,Mysql,Sql,我在一个系统上工作,由于某种原因,有人创建了一个“categories”表,但没有PK'ing该类别的ID。我刚刚发现,现在该表有一个所有行的副本,并导致我的一些查询出现问题 我的问题是:有没有一种方法可以删除重复的行,将“原始”保留在表中,而不依赖于索引 以下是从类别中选择*: +-----------+-------------+ | categoria | descripcion | +-----------+-------------+ | 1 | Int.Cons.
从类别中选择*
:
+-----------+-------------+
| 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 |
+-----------+-------------+
表上没有定义索引。在您给出的示例中,您可以非常轻松地执行此操作:
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
行中丢失一个表)在您给出的示例中,您可以非常轻松地执行此操作:
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,否则您将在下拉
行中丢失一个表)测试此操作
delete a from yourtable a1 , yourtable a2 where a1.categoria=a2.categoria
测试这个
delete a from yourtable a1 , yourtable a2 where a1.categoria=a2.categoria
您可以通过几种方式删除记录。我可能会建议使用临时表,然后正确地重新填充该表:
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);
您可以通过几种方式删除记录。我可能会建议使用临时表,然后正确地重新填充该表:
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);
如果/因为创建一个新表不是一个选项,您可以运行类似这样的操作;但您需要重复运行它,直到所有重复项都消失为止
DELETE FROM categories
WHERE (categoria, descripcion) IN (
SELECT categoria, descripcion
FROM categories
GROUP BY categoria, descripcion
HAVING COUNT(*) > 1
)
LIMIT 1
;
编辑:实际上,这应该具有临时表解决方案的优点,而不存在风险(因为真正的临时表是基于会话/连接的,如果连接失败,您将丢失数据)
显然,“NEWCOPY--”可以/应该替换为您知道的表中不存在的前缀。如果/因为创建新表不是一个选项,您可以运行类似的操作;但您需要重复运行它,直到所有重复项都消失为止
DELETE FROM categories
WHERE (categoria, descripcion) IN (
SELECT categoria, descripcion
FROM categories
GROUP BY categoria, descripcion
HAVING COUNT(*) > 1
)
LIMIT 1
;
编辑:实际上,这应该具有临时表解决方案的优点,而不存在风险(因为真正的临时表是基于会话/连接的,如果连接失败,您将丢失数据)
显然,“NEWCOPY---”可以/应该替换为一个前缀,您知道该前缀在表中不存在。我认为MySQL不支持with子句:oops对不起,我认为它在MSSQL中不支持with子句:oops对不起,我认为它在MSSQL中可以工作,但我在db中没有CREATE table权限。不知怎么的,它可以与临时表一起工作吗?您可以将数据转储到平面文件中,截断类别表并重新加载数据。这可以工作,但我在db中没有创建表的权限。不知怎么的,它能与临时表一起工作吗?你也可以将数据转储到一个平面文件中,截断类别表并重新加载数据!我只想补充一点,由于缺乏特权,我不得不创建一个临时表(创建临时表temp_categories),但一切都正常。谢谢工作得很有魅力!我只想补充一点,由于缺乏特权,我不得不创建一个临时表(创建临时表temp_categories),但一切都正常。谢谢我最终选择了临时表解决方案,但如果有人也缺乏临时表的创建权限,这可能是一个很好的选择。@Sebastianb请参阅编辑以获得另一种选择(比临时表更安全)。我最终选择了临时表解决方案,但如果有人也缺乏创建临时表的权限,这可能是一个很好的选择。@Sebastianb请参阅编辑以了解另一种选择(比临时表更安全)。