mysql n:m 关系删除查询 1242 子查询返回多于 1 行

Posted

技术标签:

【中文标题】mysql n:m 关系删除查询 1242 子查询返回多于 1 行【英文标题】:mysql n:m relationship delete query 1242 Subquery returns more than 1 row 【发布时间】:2014-02-15 01:04:16 【问题描述】:

我有两个 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】:

首先您很可能希望删除不用于其他产品的标签。例如。如果带有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演示

【讨论】:

非常感谢您的回答。感谢您抽出宝贵的时间!!我会试试你的解决方案~。祝你有美好的一天~!

以上是关于mysql n:m 关系删除查询 1242 子查询返回多于 1 行的主要内容,如果未能解决你的问题,请参考以下文章

SQL 从带有子查询的多个表中选择数据(包括来自内部连接的数据)错误:1242

JPA JPQL - 如果不使用子对象(没有主键/外键关系)并且可以删除,则返回的查询

mysql中主查询和子查询关系是啥?

mysql 删除可以用子查询吗

MySQL 表关系及多表操作(联合查询连接查询子查询)

关系数据库标准语言SQL02