0

「products」と「tags」という 2 つの SQL テーブルがあります。3 番目のテーブル「product_tags」を使用して、n:m の関係があります。

一部の商品と対応するタグをまとめて削除したい。

たとえば、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

では、どうすればこれを達成できますか?

4

1 に答える 1

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のデモです

于 2014-02-15T03:48:29.770 に答える