我正在寻找一个有效的查询来返回树的子节点。 数据结构是:
`ct_cid` int(10) unsigned NOT NULL default '0', // the data
`ct_level` int(10) unsigned NOT NULL default '0', // the level (0 = topmost)
`ct_parent` int(10) unsigned NOT NULL default '0', // parent ct_cid
我需要确保即使树被破坏或两个节点相互指向为父节点,也不会有无限循环。
答案 0 :(得分:4)
在我的博客中查看此条目,了解如何在MySQL
中有效地执行此操作:
您需要创建两个函数:
CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id_with_level_and_loop(value INT, maxlevel INT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE _id INT;
DECLARE _parent INT;
DECLARE _next INT;
DECLARE _i INT;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;
SET _parent = @id;
SET _id = -1;
SET _i = 0;
IF @id IS NULL THEN
RETURN NULL;
END IF;
LOOP
SELECT MIN(id)
INTO @id
FROM t_hierarchy
WHERE parent = _parent
AND id > _id
-- Checking for @start_with in descendants
AND id <> @start_with
AND COALESCE(@level < maxlevel, TRUE);
IF @id IS NOT NULL OR _parent = @start_with THEN
SET @level = @level + 1;
RETURN @id;
END IF;
SET @level := @level - 1;
SELECT id, parent
INTO _id, _parent
FROM t_hierarchy
WHERE id = _parent;
SET _i = _i + 1;
END LOOP;
RETURN NULL;
END
和
CREATE FUNCTION hierarchy_connect_by_iscycle(node INT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE _id INT;
DECLARE _loop INT;
DECLARE _node INT;
DECLARE EXIT HANDLER FOR NOT FOUND RETURN 0;
SET _id = COALESCE(node, @id);
SET _loop = 0;
SET _node = 0;
LOOP
SELECT parent
INTO _id
FROM t_hierarchy
WHERE id = _id;
IF _id = @start_with THEN
SET _loop := _loop + 1;
END IF;
IF _id = COALESCE(node, @id) THEN
SET _node = _node + 1;
END IF;
IF _loop >= 2 THEN
RETURN _node;
END IF;
END LOOP;
END
会模仿Oracle
的{{1}}和CONNECT BY
,并在查询中使用它们:
CONNECT_BY_ISCYCLE
答案 1 :(得分:1)
这是我的问题。 递归查询。
function select_child_ids($parent_id,&$ida) {
global $sql;
$items = $sql->select_column("SELECT id FROM test WHERE parent_id = ".$parent_id);
if ($items) {
foreach ($items as $id) {
$ida[] = $id;
select_child_ids($id,$ida);
}
} else {
return false;
}
}
注意$ sql是我的类使用mysql的示例。你可以使用自己的。 执行后,您可以读取数组$ ida
中的子元素答案 2 :(得分:0)
我使用sql查询,然后循环遍历所有记录以创建所需的数据集。
SELECT
*
FROM
category
ORDER BY
name ASC
然后
while ($categoryItem = mysql_fetch_assoc($result_category))
{
$categoryData['items'][$categoryItem['category_id']] = $categoryItem;
$categoryData['parents'][$categoryItem['parent_id']][] = $categoryItem['category_id'];
}
这对你有帮助!