如果您希望能够在没有父 id 必须低于子 id 的问题的情况下进行 SELECT,则可以使用函数。它还支持多个孩子(就像树应该做的那样),并且树可以有多个头。如果数据中存在循环,它还可以确保中断。
我想使用动态 SQL 来传递表/列名称,但 MySQL 中的函数不支持这一点。
DELIMITER $$
CREATE FUNCTION `isSubElement`(pParentId INT, pId INT) RETURNS int(11)
DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE isChild,curId,curParent,lastParent int;
SET isChild = 0;
SET curId = pId;
SET curParent = -1;
SET lastParent = -2;
WHILE lastParent <> curParent AND curParent <> 0 AND curId <> -1 AND curParent <> pId AND isChild = 0 DO
SET lastParent = curParent;
SELECT ParentId from `test` where id=curId limit 1 into curParent;
IF curParent = pParentId THEN
SET isChild = 1;
END IF;
SET curId = curParent;
END WHILE;
RETURN isChild;
END$$
在这里,test
必须将表修改为真实的表名,并且可能必须针对您的真实姓名调整列 (ParentId,Id)。
用法 :
SET @wantedSubTreeId = 3;
SELECT * FROM test WHERE isSubElement(@wantedSubTreeId,id) = 1 OR ID = @wantedSubTreeId;
结果 :
3 7 k
5 3 d
9 3 f
1 5 a
用于测试创建的 SQL:
CREATE TABLE IF NOT EXISTS `test` (
`Id` int(11) NOT NULL,
`ParentId` int(11) DEFAULT NULL,
`Name` varchar(300) NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into test (id, parentid, name) values(3,7,'k');
insert into test (id, parentid, name) values(5,3,'d');
insert into test (id, parentid, name) values(9,3,'f');
insert into test (id, parentid, name) values(1,5,'a');
insert into test (id, parentid, name) values(6,2,'o');
insert into test (id, parentid, name) values(2,8,'c');
编辑:这是一个自己测试的小提琴。它迫使我使用预定义的分隔符更改分隔符,但它有效。