如何从具有相同列值的MySQL表中删除特定行?

155

我在MySQL查询方面遇到了问题。我的表格有4列,看起来像这样:

id_users    id_product    quantity    date
 1              2              1       2013
 1              2              1       2013
 2              2              1       2013
 1              3              1       2013

id_usersid_product是来自不同表的外键。

我想要的是仅删除一行:

1     2     1    2013

其中有一个出现了两次,因此我希望将其删除。

我尝试过这个查询:

delete from orders where id_users = 1 and id_product = 2

但它将删除它们两个(因为它们是重复的)。有解决这个问题的提示吗?

6个回答

210

delete 查询添加 limit

delete from orders 
where id_users = 1 and id_product = 2
limit 1

3
这只会删除一行。如果有3行使用相同的用户和产品ID,则仍会保留2行。 - Rob
10
是的,OP说他想删除一行。这就是我的查询所做的。 - juergen d
2
是的,但我认为这不是他/她想要的。 - Rob
3
谢谢 Juergen。这就是我需要的全部内容! - Dani
3
OP需要做的是先检查哪些行是重复的,然后删除这些重复行。 - wbinky
如果有超过两个副本,只需将“limit 1”修改为“limit(select count(*)-1 from orders where [适当的筛选器以选择所有重复项])”即可。 - sisisisi

64

每个表都应该有一个主键(由单个或多个列组成),在关系型数据库中,重复的行是没有意义的。不过你可以使用 LIMIT 限制删除行的数量:

DELETE FROM orders WHERE id_users = 1 AND id_product = 2 LIMIT 1

但这只是解决了你当前的问题,你应该通过定义主键来处理更大的问题。


1
值得一提的是,在关系型数据库中,主键应该是唯一的。 - Paul
1
@Paul 这正是我要说的。但不要忘记唯一键并不一定意味着主键。 - Ryan Fung

20
你需要指定要删除的行数。针对你的情况(我假设你只想保留一行),可以像这样操作:
DELETE FROM your_table WHERE id_users=1 AND id_product=2
LIMIT (SELECT COUNT(*)-1 FROM your_table WHERE id_users=1 AND id_product=2)

谢谢你,Rob,但不用了……我只想删除一行,而不是保留一行。 - Dani
这在5.5.40版本中对我不起作用,它会抛出语法错误。正如此处所述:https://dev59.com/ZnRB5IYBdhLWcg3wl4IQ#578926,似乎我们不能使用子查询来指定LIMIT子句的值。对于任何试图以这种方式处理事情的人,请查看这个链接:https://dev59.com/ZnRB5IYBdhLWcg3wl4IQ。 - Bharadwaj Srigiriraju

8

设计表格的最佳方式是添加一个自动增量行并保持为主键,这样我们就可以避免上述问题。


1
或者一个永久行。我知道这是一个老问题,但我认为我应该说一下。ID被用于这种情况。如果你担心空间:BIGINT只有8个字节! - Ismael Miguel

5

已经有了通过LIMIT删除行的答案。理想情况下,您的表中应该有主键。但如果没有,我会给出其他方法:

  1. 通过创建唯一索引

在您的示例中,我看到id_users和id_product应该是唯一的。

ALTER IGNORE TABLE orders ADD UNIQUE INDEX unique_columns_index (id_users, id_product)

这些代码可以删除含有相同数据的重复行。

但是如果即使使用了 IGNORE 子句,你仍然遇到错误,请尝试以下方法:

ALTER TABLE orders ENGINE MyISAM;
ALTER IGNORE TABLE orders ADD UNIQUE INDEX unique_columns_index (id_users, id_product)
ALTER TABLE orders ENGINE InnoDB; 
  1. 通过重新创建表格

如果有多行具有重复值,则还可以重新创建表格。

RENAME TABLE `orders` TO `orders2`;

CREATE TABLE `orders` 
SELECT * FROM `orders2` GROUP BY id_users, id_product;

1

您需要为每一行添加一个自动递增的ID,之后您可以通过其ID删除该行。 因此,您的表将为每一行和id_user、id_product等拥有唯一的ID。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接