mysql删除与其他元素没有链接的元素

标签 mysql sql sql-delete

我有一个包含 3 个表的数据库:

  • 用户
  • Users_cards
  • 卡片

users_cards 有两列:

  • user_id(是Users.id的外键)
  • card_id(是 Cards.id 的外键)

userscards表有自己的id作为主键,users_cards的两列是它们的外键,级联删除选项,所以当我从 cards 中删除一张卡时,它也会从 users_cards 中删除,与 users 相同。

而且,我希望当我删除 users_cards 表的一行时,如果该卡没有更多用户,也就是说,如果该行是 card_id< 的唯一行 出现在表格中,它也必须从 cards 中删除。

实现此目标的最佳方法是什么?可以“自动”完成,还是每次从 users_cards 中删除一行时都必须检查?

最佳答案

Can it be done "automatically" or do I have to check every time I delete one row from users_cards this?

自动取决于你的意思。 我会使用触发器:

DELIMITER $$

CREATE DEFINER=CURRENT_USER TRIGGER `name_of_this_trigger`
AFTER DELETE ON `users_cards` FOR EACH ROW
BEGIN

    DELETE FROM `cards` WHERE `id` NOT IN (SELECT DISTINCT `card_id` FROM `users_cards`);

END $$

DELIMITER ;

如果你在你的数据库上执行它,它会添加一个触发器来运行并检查无用户卡,并在每次对 users_cards 表进行 DELETE 查询后删除它们而不会造成任何额外的麻烦。 但是,如果 users_cards 已被级联事件删除,它不会运行,因此无法删除任何可能没有用户的卡片。 所以,你可以做两件事。无:垃圾将在 users_cards 的下一个 DELETE 查询中被清除。或者;您可以添加另一个触发器,它在 users 表上的 DELETE 查询之后运行,就像这样(删除由于级联而现在没有 users_cards 的任何潜在卡片删除源自用户):

DELIMITER $$

CREATE DEFINER=CURRENT_USER TRIGGER `name_this_very_trigger`
AFTER DELETE ON `users` FOR EACH ROW
BEGIN

    DELETE FROM `cards` WHERE `id` NOT IN (SELECT DISTINCT `card_id` FROM `users_cards`);

END $$

DELIMITER ;

仅供引用:如果您注意到,触发器声明后只有一个语句,所以您甚至不需要 BEGIN ... END block ,这意味着 DELIMITER废话也不必了。

如果有帮助,请告诉我!

ps.:看在上帝的份上; 请不要使用复数表名。您是在命名存储在表中的实体而不是表本身。

关于mysql删除与其他元素没有链接的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43485092/

相关文章:

c# - 如何将 C# 中的 2 个 SQL 过程的结果附加到单个 CSV 文件中?

javascript - 如果 1 个值大于另一个值,则按钮提交时发出通知

mysql - 来自同一张表的两个复合键

MySQL - 过滤日期最大的记录

mysql - 删除旧记录 - MySQL

java - 删除数据库中间的一些行后,有什么方法可以滚动 SQL 中的所有行吗?

mysql - 如何使用 Sequelize 将每行 2 列相乘并对所有结果求和?

sql - 在表格中间插入新列?

mysql - SQL 选择模式,例如column_name

MySQL删除连接错误