2014-02-15 73 views
0

我有两个SQL表,'products'和'tags'。他们有一个n:m的关系,使用第三个表'product_tags'。mysql n:m关系删除查询1242子查询返回多于1行

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

比方说,我已经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 

那么,我该如何做到这一点?

回答

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演示

+0

我真的很感激你的答案。感谢您的时间!我会尝试你的解决方案〜。有一个美好的一天〜! – coverboy

相关问题