mysql n:m relationship delete query 1242子查询返回多行

时间:2014-02-15 01:04:16

标签: mysql relationship sql-delete nm mysql-error-1242

我有两个SQL表,'产品'和'标签'。他们有一个n:m关系,使用第三个表'product_tags'。

我想一起删除一些产品和相应的标签。

比方说,我有products.product_id = 3,该产品有tags.tag_id = 3,tags.tag_id = 5

product_tags表

product_id 3 tag_id 3
product_id 3 tag_id 5

delete from tags where tag_id in (select product_tags.tag_id from product_tags where product_id =3);
delete from tags where tag_in = any (select product_tags.tag_id from product_tags where product_id=3);

要么产生

0 row(s) affected, 1 warning(s): 1242 Subquery returns more than 1 row

那么,我该怎么做呢?

1 个答案:

答案 0 :(得分:0)

首先您最有可能想要删除未与其他产品一起使用的标签。例如。如果带有tag_id = 3的标记也与其他产品一起使用,请说product_id = 1,那么您就不应该删除此标记。

其次如果您使用外键强制执行正确的父子关系,则必须按正确的顺序从表中删除行。首先,您应该从product_tags删除行。

据说,您的代码可以安全地删除产品以及未使用的标签

DELIMITER //
CREATE PROCEDURE delete_product(IN _product_id INT)
BEGIN
  DROP TEMPORARY TABLE IF EXISTS tmp_tags_to_be_deleted;

  START TRANSACTION;

  CREATE TEMPORARY TABLE tmp_tags_to_be_deleted(tag_id INT PRIMARY KEY);
  INSERT INTO tmp_tags_to_be_deleted
  SELECT tag_id
    FROM product_tags t
   WHERE product_id = _product_id
     AND NOT EXISTS
  (
    SELECT *
      FROM product_tags
     WHERE tag_id = t.tag_id
       AND product_id <> t.product_id
  );

  DELETE 
    FROM product_tags
   WHERE product_id = _product_id;

  DELETE t
    FROM tags t JOIN tmp_tags_to_be_deleted x
      ON t.tag_id = x.tag_id;

  DELETE 
    FROM products
   WHERE product_id = _product_id;

  COMMIT;
END//
DELIMITER ;

用法:

CALL delete_product(3);

这是 SQLFiddle 演示