Java Php Mysql 递归查询 查询当前节点下的所有子节点 包含当前节点返回列表
创始人
2024-06-03 15:52:45
0

递归查询

  • MySQL
    • 1. WITH RECURSIVE语法
    • 2. 子查询
    • 3. 函数
  • JAVA代码
    • 执行多次SQL
    • 执行一次SQL
  • PHP代码

MySQL

1. WITH RECURSIVE语法

使用了MySQL的WITH RECURSIVE语法。首先,它选取了当前节点作为起点,然后在递归的过程中找到了所有它的子节点。最后,它输出了所有找到的节点的标识符。
请注意将查询中的[当前节点的ID]替换为你要查询的节点的ID。

WITH RECURSIVE cte AS (SELECT id, parent_idFROM tree_tableWHERE id = [当前节点的ID]UNION ALLSELECT t.id, t.parent_idFROM tree_table tINNER JOIN cte ON t.parent_id = cte.id
)
SELECT id FROM cte;

2. 子查询

如果你使用的MySQL版本不支持WITH RECURSIVE语法,或者你想尝试不使用WITH RECURSIVE的方法;
这个查询使用了两个子查询。第一个子查询选取了当前节点的ID,并且作为递归查询的起点。第二个子查询从tree_table表中自联结,以查找当前节点的所有子节点。然后,使用JOIN操作将这些子节点与tree_table表中的原始记录匹配,从而得到当前节点下的所有子节点。
请注意将查询中的[当前节点的ID]替换为你要查询的节点的ID。

SELECT t1.id
FROM tree_table t1
JOIN (SELECT id FROM tree_table WHERE id = [当前节点的ID]UNION ALLSELECT t2.id FROM tree_table t2 JOIN tree_table t3 ON t2.parent_id = t3.idWHERE t3.id = [当前节点的ID]
) t4
ON t1.id = t4.id;

3. 函数

编写一个存储过程或函数来实现递归查询;将查询中的[当前节点的ID]替换为你要查询的节点的ID。

DELIMITER $$CREATE FUNCTION get_all_children (node_id INT) RETURNS TEXT
BEGINDECLARE child_ids TEXT DEFAULT '';DECLARE child_id INT;SELECT GROUP_CONCAT(id) INTO child_ids FROM tree_table WHERE parent_id = node_id;IF child_ids IS NOT NULL THENSET child_ids = CONCAT(child_ids, ',', get_all_children(child_id));END IF;RETURN child_ids;
END$$DELIMITER ;

这个函数使用递归的方式来查询当前节点下的所有子节点。首先,它查找所有直接子节点的ID,并使用GROUP_CONCAT函数将这些ID连接成一个逗号分隔的字符串。然后,对于每个子节点,函数递归调用自己来查找它的子节点,并将它们的ID也连接到返回值中。最后,函数返回一个包含当前节点下所有子节点ID的逗号分隔字符串。

请注意将函数中的tree_table和id和parent_id字段名称替换为你实际使用的表和字段名称。你可以使用以下语句来调用这个函数:

SELECT get_all_children([当前节点的ID]);

将查询中的[当前节点的ID]替换为你要查询的节点的ID。

JAVA代码

执行多次SQL

这个Java方法使用递归的方式来查询当前节点下的所有子节点。首先,它查询所有直接子节点的ID。然后,对于每个子节点,方法递归调用自己来查找它的子节点。最后,方法返回一个包含当前节点下所有子节点ID的列表。

请注意将示例代码中的tree_table和id和parent_id字段名称替换为你实际使用的表和字段名称,以及将数据库连接的URL、用户名和密码替换为你的实际连接信息。

import java.sql.*;
import java.util.ArrayList;
import java.util.List;public class TreeUtils {public static List getAllChildren(int nodeId, Connection conn) throws SQLException {List childIds = new ArrayList<>();// 查询所有直接子节点PreparedStatement stmt = conn.prepareStatement("SELECT id FROM tree_table WHERE parent_id = ?");stmt.setInt(1, nodeId);ResultSet rs = stmt.executeQuery();// 对于每个子节点,递归调用自己来查找它的子节点while (rs.next()) {int childId = rs.getInt("id");childIds.add(childId);childIds.addAll(getAllChildren(childId, conn));}rs.close();stmt.close();return childIds;}// 使用示例public static void main(String[] args) {Connection conn = null;try {// 创建数据库连接conn = DriverManager.getConnection("jdbc:mysql://localhost/mydatabase", "root", "password");// 查询当前节点的所有子节点List childIds = getAllChildren([当前节点的ID], conn);// 输出所有子节点的IDSystem.out.println(childIds);} catch (SQLException e) {e.printStackTrace();} finally {try {if (conn != null) {conn.close();}} catch (SQLException e) {e.printStackTrace();}}}
}

执行一次SQL

这个Java方法首先执行SQL语句查询所有节点,然后将结果集转换为列表。接着使用递归的方式来查询树结构。它遍历列表中的每个节点,如果节点的父ID等于指定的父ID,则将该节点作为当前节点,递归查询该节点的子节点,并将子节点作为嵌套的子树添加到当前节点。最后,方法返回一个包含根节点的树结构的Map对象。

请注意将示例代码中的tree_table和id和parent_id字段名称替换为你实际使用的表和字段名称,以及将数据库连接的URL、用户名和密码

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class TreeUtils {public static Map buildTree(List> list, int parentId) {Map node = new HashMap<>();for (Map item : list) {int id = (int) item.get("id");int pid = (int) item.get("parent_id");if (pid == parentId) {// 设置当前节点的属性node.put("id", id);node.put("name", item.get("name"));// 递归查询当前节点的子节点List> children = new ArrayList<>();for (Map child : list) {int childPid = (int) child.get("parent_id");if (childPid == id) {children.add(buildTree(list, id));}}// 如果有子节点,则将子节点添加到当前节点if (!children.isEmpty()) {node.put("children", children);}}}return node;}// 使用示例public static void main(String[] args) {Connection conn = null;try {// 创建数据库连接conn = DriverManager.getConnection("jdbc:mysql://localhost/mydatabase", "root", "password");// 执行SQL语句查询所有节点PreparedStatement stmt = conn.prepareStatement("SELECT * FROM tree_table");ResultSet rs = stmt.executeQuery();// 将结果集转换为列表List> list = new ArrayList<>();while (rs.next()) {Map item = new HashMap<>();item.put("id", rs.getInt("id"));item.put("name", rs.getString("name"));item.put("parent_id", rs.getInt("parent_id"));list.add(item);}// 构建树结构Map tree = buildTree(list, 0);// 输出树结构System.out.println(tree);rs.close();stmt.close();} catch (SQLException e) {e.printStackTrace();} finally {try {if (conn != null) {conn.close();}} catch (SQLException e) {e.printStackTrace();}}}
}

PHP代码

这个PHP函数使用递归的方式来查询当前节点下的所有子节点。首先,它查询所有直接子节点的ID。然后,对于每个子节点,函数递归调用自己来查找它的子节点。最后,函数返回一个包含当前节点下所有子节点ID的数组。

请注意将示例代码中的tree_table和id和parent_id字段名称替换为你实际使用的表和字段名称。如果你使用的是其他语言或框架,可以根据类似的逻辑编写递归函数或方法来实现递归查询。

function get_all_children($node_id, $mysqli) {$child_ids = array();// 查询所有直接子节点$result = $mysqli->query("SELECT id FROM tree_table WHERE parent_id = $node_id");// 对于每个子节点,递归调用自己来查找它的子节点while ($row = $result->fetch_assoc()) {$child_id = $row['id'];$child_ids[] = $child_id;$child_ids = array_merge($child_ids, get_all_children($child_id, $mysqli));}return $child_ids;
}// 使用示例
$mysqli = new mysqli('host', 'username', 'password', 'database');
$node_id = 1; // 替换为你要查询的节点的ID
$child_ids = get_all_children($node_id, $mysqli);
print_r($child_ids);

相关内容

热门资讯

资本界金控(00204.HK)... 格隆汇7月2日丨资本界金控(00204.HK)公告,公司近期与江苏福万代科技信息有限公司("福万代"...
新希望:独立董事彭龙接受纪律审... 转自:财联社【新希望:独立董事彭龙接受纪律审查和监察调查】财联社7月2日电,新希望公告,公司独立董事...
3岁萌娃迷路街头,妈妈急疯!两... 来源:杭州公安 “你好 我在天万街与羊头坝路交叉口的桥上 这边有个小孩子找不到家人一直在哭” 6月2...
中考成绩单|低波策略业绩盘点 (转自:国泰基金微幸福)
华菱钢铁:投资者建议连续三年回... 投资者提问:回购注销是财务手段里提升pb最稳定最可靠最有效的方式,在pb回升到1之前,每年分红可以少...
今年前5个月销量排名前十位轿车... 转自:北京商报北京商报讯(记者 刘晓梦)7月2日,据中国汽车工业协会统计分析,今年前5个月,销量排名...
法国已有2人死于热浪 转自:新华社新华社巴黎7月2日电(记者罗毓)法国商业调频电视台2日上午报道,最近该国遭遇强热浪天气,...
赛意信息(300687.SZ)... 格隆汇7月2日丨赛意信息(300687.SZ)公布,截至2025年6月30日,公司通过股份回购专用证...
比亚迪汽车:海洋网累计销售超5... 7月2日,比亚迪汽车官方微博显示,比亚迪海洋网6月热销196766辆,同比增长24.6%。2025年...
能特科技:拟以3亿元-5亿元回... 格隆汇7月2日|能特科技公告,公司拟使用自有资金及自筹资金,本次回购股份将全部用于注销并相应减少注册...