2013-08-22 49 views
130

我在MySQL中遇到了一个问题。我的表有4列,它看起来是这样的:如何从具有相同列值的mysql表中删除某一行?

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 

但它会删除他们两人(因为它们是重复的)。解决这个问题的任何提示?

回答

167

添加limitdelete查询

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

这只会删除一行。如果有3个用户和产品ID,则2将保留。 – Rob

+8

是的,OP说(s)他想删除1行。这是我的查询所做的。 –

+2

是的,但我认为这不是他/她想要的。 – Rob

57

所有的表都应该有一个主键(由单个或多列),重复行就没有意义了在关系数据库中。您可以使用限制虽然LIMIT删除的行数:

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

但是,这只是解决您的本期,你一定要在更大的问题通过定义主键工作。

+0

发现它,谢谢你们! – Dani

+1

这很好的提及主键在关系数据库中应该是唯一的。 – Paul

+1

@保罗这正是我要说的。但不要忘记独特的钥匙不一定意味着主钥匙。 –

17

您需要指定应该删除的行数。你的情况(我假设你只是想保持一个),这是可以做到这样的:设计表

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) 
+0

谢谢Rob,但是没有...我只想删除一行,而不是只保留一行 – Dani

+0

这在5.5.40中不适用于我,它会引发语法错误。正如在这里提到的:http://stackoverflow.com/a/578926/1076075,看起来我们不能使用子查询来指定LIMIT子句的值。对于任何想以这种方式进行操作的人,请查看:http://stackoverflow.com/q/578867/1076075 –

6

最好的办法是增加一个临时一行作为自动递增,并保持作为主键。所以我们可以避免上述问题。

+1

或者是一个永久性的行。我知道这是一个古老的问题,但我应该说。身份证是用于这种情况。如果你担心空间:一个BIGINT只有8个字节! –

3

已经有删除行LIMIT的答案。理想情况下,你应该在你的表中有主键。但如果没有。

我会给其他方法:

  1. 通过创建Unique index

我看到id_users和id_product应该在你的例子是独一无二的。

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

这将删除与同一数据重复的行。

但是,如果你仍然得到一个错误,即使你使用忽略条款,试试这个:

ALTER TABLE orders ENGINE MyISAM; 
ALTER IGNORE TABLE orders ADD UNIQUE INDEX unique_columns_index (id_users, id_product) 
ALTER TABLE orders ENGINE InnoDB; 
  • 通过创建表再次
  • 如果有是具有重复值的多行,那么您也可以重新创建表

    RENAME TABLE `orders` TO `orders2`; 
    
    CREATE TABLE `orders` 
    SELECT * FROM `orders2` GROUP BY id_users, id_product; 
    
    相关问题