[英]How to find all child rows in MySQL?
我有一个层次结构系统设置程序,用于在数据库中存储项目的级别和父ID。 我要弄清楚的是,如何找到用户选择的所有子行。 这是表结构的示例:
+----+---------+----------+-------+
| Id | label | parentid | level |
+----+---------+----------+-------+
| 1 | honda | 0 | 1 |
| 2 | accord | 1 | 2 |
| 3 | civic | 1 | 2 |
| 4 | element | 1 | 2 |
| 5 | v4 | 2 | 3 |
| 6 | v6 | 2 | 3 |
+----+---------+----------+-------+
因此,如果有人删除honda
,我将如何删除层次结构中的所有内容? 数据库将只能降级到3级。
我昨天发布了同样的答案
更新:
以下是基于以上链接的function
,但已根据您的DELETE
要求进行了量身定制
CREATE PROCEDURE `delete_relations`(`_id` INT)
BEGIN
DECLARE delete_row_ids varchar(200);
DECLARE id, id2 varchar(200);
DECLARE rows_affected int;
SET delete_row_ids = _id;
SET id = _id;
SET id2 = id;
WHILE id2 IS NOT NULL DO
SET id = NULL;
SELECT GROUP_CONCAT( hierarchical_data.id ), CONCAT( GROUP_CONCAT( hierarchical_data.ID ),',',delete_row_ids) INTO id, delete_row_ids FROM hierarchical_data WHERE FIND_IN_SET( parentid , id2 ) GROUP BY parentid ;
SET id2 = id;
END WHILE;
DELETE FROM hierarchical_data where FIND_IN_SET(hierarchical_data.id, delete_row_ids);
SELECT row_count() INTO rows_affected;
if rows_affected > 0 THEN
SELECT delete_row_ids as row_ids_deleted;
ELSE
SELECT 'NO_ROWS_DELETED';
END IF;
END//
采用
CALL delete_relations(1)
删除id = 1 honda
所有条目及其关系
希望对您有所帮助
将:id
替换为以下要删除的根条目ID:
DELETE FROM table
WHERE
id = :id
OR id IN (
-- first level
SELECT DISTINCT id sid
FROM table
WHERE parentid = :id
-- second level
UNION
SELECT DISTINCT t2.id sid
FROM table t1
INNER JOIN table t2
ON t1.id = t2.parentid
WHERE t1.parentid = :id
-- third level
UNION
SELECT DISTINCT t3.id sid
FROM table t1
INNER JOIN table t2
ON t1.id = t2.parentid
INNER JOIN table t3
ON t2.id = t3.parentid
WHERE t1.id = :id
)
请注意,您有3个级别,但是根节点占据了其中一个级别,这意味着您实际上只需要选择子级和孙级。 上面的查询会再执行一个级别(第3个级别),因此您可以将第-- third level
之后的部分删除到右括号。
假设您使用的是具有触发器的MySQL 5,则可以在删除触发器之前编写一个小的触发器,以轻松实现此目的。 我没有完全检查语法,但是将与以下内容大致匹配:
CREATE TRIGGER tr_tablename_bd BEFORE DELETE ON tablename
FOR EACH ROW BEGIN
DELETE FROM tablename WHERE parentID = deleted.id
END;
上面的代码还将适用于无限级别,而不仅仅是3个级别。 您将需要删除一行,触发器将删除以下级别的数据行或将已删除的行标记为parentID的行。
但是,我隐约记得MySQL的一个问题,即它无法启动级联触发器。 意味着MySQL由于触发另一个触发器而未能触发触发器。 如果您正在使用的MySQL版本(甚至最新版本)中仍然存在该错误,则此代码将不起作用。 但是,从理论上讲,这是完全可以的,并且可以在肯定有触发器的所有其他数据库上工作。 对于MySQL,您只需要检查他们是否能够解决该错误!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.