码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • MySQL 根据【父ID】获取【所有子节点】


    MySQL根据父节点ID查出所有子节点

    • 测试表
    • SQL
      • 分析
    • 用JS生成SQL
    • 参考资料

    测试表

    CREATE TABLE `dept` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` longtext,
      `pid` int(11) DEFAULT NULL,
      `status` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门表';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    SQL

    SELECT * 
    FROM (
        SELECT
    		t1.*,
            IF(FIND_IN_SET(`pid`, @pids) > 0, @pids := CONCAT(@pids, ',', `id`), 0) AS ancestors
        FROM
            ( SELECT * FROM `dept` AS t WHERE t.`status` = 1 ORDER BY t.`id` ASC ) AS t1,
            ( SELECT @pids := 14 ) AS t2
    ) AS t3
    WHERE
    	ancestors != 0
    	or `id` = 14;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    分析

    1. t1:获取所有状态正常的数据并升序排列。
    2. t2:初始化@pids变量,它用于获取每条记录时缓存父ID。
    3. FIND_IN_SET查询当前记录的父ID在@pids中的位置。找不到就返回0。
      3.1. 找到就将父id拼接到@pids末尾,以便下一条记录继续在@pids中找自己的父id。
    4. 每一条记录都基于前一条执行时得到的@pids进行判断。
    5. 总结:使用此方案的前提是:
      5.1. 所有结点的【id】必需大于【父id】: id > pid。
      5.2. 所有 id 整体是一个升序状态。
      5.3. 如果5.1无法满足,有其他字段能保证查 t1 时,结点可以按【根>干>叶】进行升序排列也行。

    用JS生成SQL

    var 结果字段 = '*';
    var 表名 = '`sys_dept`';
    var 主键 = '`id`';
    var 父主键 = '`pid`';
    var 状态 = '`status`';
    var 要查的主键 = 14;
    var 包含当前结点 = true;
    
    var sql = `SELECT ${结果字段} 
    FROM (
        SELECT
    		t1.*,
            IF(FIND_IN_SET(${父主键}, @pids) > 0, @pids := CONCAT(@pids, ',', ${主键}), 0) AS ancestors
        FROM
            ( SELECT * FROM ${表名} AS t WHERE t.${状态} = 1 ORDER BY t.${主键} ASC ) AS t1,
            ( SELECT @pids := ${要查的当前主键} ) AS t2
    ) AS t3
    WHERE
    	ancestors != 0
    	${包含当前结点 ? `or ${主键} = ${要查的主键}` : ''};`;
    console.log(sql);
    copy(sql);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    参考资料

    笑虾:MySQL - 学习笔记 - SELECT语句

    博客园 - 张亮java:https://www.cnblogs.com/zhangliang88/p/15910781.html

  • 相关阅读:
    SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(1)
    一文了解函数设计的最佳实践
    【ARC 自动引用计数 Objective-C语言】
    Java程序猿搬砖笔记(十)
    Python | 打包 .py 为可执行文件.exe
    TypeScript开启
    uniapp da-tree插件 代码和结构分析
    C++12 ---对象于对象的关系
    HPA总结
    Java.lang.Class类 getDeclaredConstructors()方法有什么功能呢?
  • 原文地址:https://blog.csdn.net/jx520/article/details/126778144
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号