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);

相关内容

热门资讯

中证A500ETF摩根(560... 8月22日,截止午间收盘,中证A500ETF摩根(560530)涨1.19%,报1.106元,成交额...
A500ETF易方达(1593... 8月22日,截止午间收盘,A500ETF易方达(159361)涨1.28%,报1.104元,成交额1...
何小鹏斥资约2.5亿港元增持小... 每经记者|孙磊    每经编辑|裴健如 8月21日晚间,小鹏汽车发布公告称,公司联...
中证500ETF基金(1593... 8月22日,截止午间收盘,中证500ETF基金(159337)涨0.94%,报1.509元,成交额2...
中证A500ETF华安(159... 8月22日,截止午间收盘,中证A500ETF华安(159359)涨1.15%,报1.139元,成交额...
科创AIETF(588790)... 8月22日,截止午间收盘,科创AIETF(588790)涨4.83%,报0.760元,成交额6.98...
创业板50ETF嘉实(1593... 8月22日,截止午间收盘,创业板50ETF嘉实(159373)涨2.61%,报1.296元,成交额1...
港股异动丨航空股大幅走低 中国... 港股航空股大幅下跌,其中,中国国航跌近7%表现最弱,中国东方航空跌近5%,中国南方航空跌超3%,美兰...
电网设备ETF(159326)... 8月22日,截止午间收盘,电网设备ETF(159326)跌0.25%,报1.198元,成交额409....
红利ETF国企(530880)... 8月22日,截止午间收盘,红利ETF国企(530880)跌0.67%,报1.034元,成交额29.0...