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


153

我在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_users并且id_product是来自不同表的外键。

我要删除的只是一行:

1     2     1    2013

它出现两次,所以我只想删除它。

我试过这个查询:

delete from orders where id_users = 1 and id_product = 2

但是它将删除它们两个(因为它们是重复的)。关于解决此问题的任何提示?

Answers:


208

limit删除查询添加

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

3
这只会删除一行。如果该用户和产品ID共有3个,则剩下2个。
罗布

10
是的,OP说他想删除1行。那就是我的查询。
juergen d 2013年

2
是的,但我认为这不是他/她想要的。
罗布

3
谢谢Juergen。这就是我所需要的!
Dani

3
OP真正需要做的是首先检查哪些行重复,然后删除重复的行。
wbinky 2014年

64

所有表都应有一个主键(由一个或多个列组成),在关系数据库中没有重复的行是没有意义的。您可以使用以下方法限制删除行的数量LIMIT

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

但这仅解决了您当前的问题,您绝对应该通过定义主键来解决更大的问题。


1
值得一提的是,主键在关系数据库中应该是唯一的。
保罗

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中,这对我不起作用,它引发语法错误。如此处所述:stackoverflow.com/a/578926/1076075,似乎我们不能使用子查询来指定LIMIT子句的值。对于尝试通过这种方式进行操作的任何人,请查看以下内容:stackoverflow.com/q/578867/1076075
Bharadwaj Srigiriraju 2014年

8

设计表的最佳方法是添加一个临时行作为自动增量并保留为主键。因此我们可以避免上述问题。


1
或永久排。我知道这是一个老问题,但是我应该说。Id用于这种情况。如果您担心空间:BIGINT仅8个字节!
Ismael Miguel 2014年

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;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.