• 一句SQL实现MYSQL的递归查询


    众所周知,目前的mysql版本中并不支持直接的递归查询,但是通过递归到迭代转化的思路,还是可以在一句SQL内实现树的递归查询的。这个得益于Mysql允许在SQL语句内使用@变量。以下是示例代码。

    创建表格

    CREATE TABLE `treenodes` (
        `id` int , -- 节点ID
        `nodename` varchar (60), -- 节点名称
        `pid` int  -- 节点父ID
    ); 

    插入测试数据

    复制代码
    INSERT INTO `treenodes` (`id`, `nodename`, `pid`) VALUES
    ('1','A','0'),('2','B','1'),('3','C','1'),
    ('4','D','2'),('5','E','2'),('6','F','3'),
    ('7','G','6'),('8','H','0'),('9','I','8'),
    ('10','J','8'),('11','K','8'),('12','L','9'),
    ('13','M','9'),('14','N','12'),('15','O','12'),
    ('16','P','15'),('17','Q','15'),('18','R','3'),
    ('19','S','2'),('20','T','6'),('21','U','8');
    复制代码

    查询语句

    复制代码
     SELECT id AS ID,pid AS 父ID ,levels AS 父到子之间级数, paths AS 父到子路径 FROM (
         SELECT id,pid,
         @le:= IF (pid = 0 ,0,  
             IF( LOCATE( CONCAT('|',pid,':'),@pathlevel)   > 0  ,      
                      SUBSTRING_INDEX( SUBSTRING_INDEX(@pathlevel,CONCAT('|',pid,':'),-1),'|',1) +1
            ,@le+1) ) levels
         , @pathlevel:= CONCAT(@pathlevel,'|',id,':', @le ,'|') pathlevel
          , @pathnodes:= IF( pid =0,',0', 
               CONCAT_WS(',',
               IF( LOCATE( CONCAT('|',pid,':'),@pathall) > 0  , 
                   SUBSTRING_INDEX( SUBSTRING_INDEX(@pathall,CONCAT('|',pid,':'),-1),'|',1)
                  ,@pathnodes ) ,pid  ) )paths
        ,@pathall:=CONCAT(@pathall,'|',id,':', @pathnodes ,'|') pathall 
            FROM  treenodes, 
        (SELECT @le:=0,@pathlevel:='', @pathall:='',@pathnodes:='') vv
        ORDER BY  pid,id
        ) src
    ORDER BY id
    复制代码

    最后的结果如下:

    复制代码
        ID   父ID  父到子之间级数  父到子路径
    ------  ------  ------------  ---------------
         1       0        0           ,0             
         2       1        1           ,0,1           
         3       1        1           ,0,1           
         4       2        2           ,0,1,2         
         5       2        2           ,0,1,2         
         6       3        2           ,0,1,3         
         7       6        3           ,0,1,3,6       
         8       0        0           ,0             
         9       8        1           ,0,8           
        10       8        1           ,0,8           
        11       8        1           ,0,8           
        12       9        2           ,0,8,9         
        13       9        2           ,0,8,9         
        14      12        3           ,0,8,9,12      
        15      12        3           ,0,8,9,12      
        16      15        4           ,0,8,9,12,15   
        17      15        4           ,0,8,9,12,15   
        18       3        2           ,0,1,3         
        19       2        2           ,0,1,2         
        20       6        3           ,0,1,3,6       
        21       8        1           ,0,8       
    复制代码

     http://www.cnblogs.com/dukou/p/4691543.html

    --创建表
     
    DROP TABLE IF EXISTS `t_areainfo`;
    CREATE TABLE `t_areainfo` (
     `id` int(11) NOT '0' AUTO_INCREMENT,
     `levelint(11) DEFAULT '0',
     `namevarchar(255) DEFAULT '0',
     `parentId` int(11) DEFAULT '0',
     `status` int(11) DEFAULT '0',
     PRIMARY KEY (`id`)
    ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    --初始数据
     
    INSERT INTO `t_areainfo` VALUES ('1''0''中国''0''0');
    INSERT INTO `t_areainfo` VALUES ('2''0''华北区''1''0');
    INSERT INTO `t_areainfo` VALUES ('3''0''华南区''1''0');
    INSERT INTO `t_areainfo` VALUES ('4''0''北京''2''0');
    INSERT INTO `t_areainfo` VALUES ('5''0''海淀区''4''0');
    INSERT INTO `t_areainfo` VALUES ('6''0''丰台区''4''0');
    INSERT INTO `t_areainfo` VALUES ('7''0''朝阳区''4''0');
    INSERT INTO `t_areainfo` VALUES ('8''0''北京XX区1''4''0');
    INSERT INTO `t_areainfo` VALUES ('9''0''北京XX区2''4''0');
    INSERT INTO `t_areainfo` VALUES ('10''0''北京XX区3''4''0');
    INSERT INTO `t_areainfo` VALUES ('11''0''北京XX区4''4''0');
    INSERT INTO `t_areainfo` VALUES ('12''0''北京XX区5''4''0');
    INSERT INTO `t_areainfo` VALUES ('13''0''北京XX区6''4''0');
    INSERT INTO `t_areainfo` VALUES ('14''0''北京XX区7''4''0');
    INSERT INTO `t_areainfo` VALUES ('15''0''北京XX区8''4''0');
    INSERT INTO `t_areainfo` VALUES ('16''0''北京XX区9''4''0');
    INSERT INTO `t_areainfo` VALUES ('17''0''北京XX区10''4''0');
    INSERT INTO `t_areainfo` VALUES ('18''0''北京XX区11''4''0');
    INSERT INTO `t_areainfo` VALUES ('19''0''北京XX区12''4''0');
    INSERT INTO `t_areainfo` VALUES ('20''0''北京XX区13''4''0');
    INSERT INTO `t_areainfo` VALUES ('21''0''北京XX区14''4''0');
    INSERT INTO `t_areainfo` VALUES ('22''0''北京XX区15''4''0');
    INSERT INTO `t_areainfo` VALUES ('23''0''北京XX区16''4''0');
    INSERT INTO `t_areainfo` VALUES ('24''0''北京XX区17''4''0');
    INSERT INTO `t_areainfo` VALUES ('25''0''北京XX区18''4''0');
    INSERT INTO `t_areainfo` VALUES ('26''0''北京XX区19''4''0');
    INSERT INTO `t_areainfo` VALUES ('27''0''北京XX区1''4''0');
    INSERT INTO `t_areainfo` VALUES ('28''0''北京XX区2''4''0');
    INSERT INTO `t_areainfo` VALUES ('29''0''北京XX区3''4''0');
    INSERT INTO `t_areainfo` VALUES ('30''0''北京XX区4''4''0');
    INSERT INTO `t_areainfo` VALUES ('31''0''北京XX区5''4''0');
    INSERT INTO `t_areainfo` VALUES ('32''0''北京XX区6''4''0');
    INSERT INTO `t_areainfo` VALUES ('33''0''北京XX区7''4''0');
    INSERT INTO `t_areainfo` VALUES ('34''0''北京XX区8''4''0');
    INSERT INTO `t_areainfo` VALUES ('35''0''北京XX区9''4''0');
    INSERT INTO `t_areainfo` VALUES ('36''0''北京XX区10''4''0');
    INSERT INTO `t_areainfo` VALUES ('37''0''北京XX区11''4''0');
    INSERT INTO `t_areainfo` VALUES ('38''0''北京XX区12''4''0');
    INSERT INTO `t_areainfo` VALUES ('39''0''北京XX区13''4''0');
    INSERT INTO `t_areainfo` VALUES ('40''0''北京XX区14''4''0');
    INSERT INTO `t_areainfo` VALUES ('41''0''北京XX区15''4''0');
    INSERT INTO `t_areainfo` VALUES ('42''0''北京XX区16''4''0');
    INSERT INTO `t_areainfo` VALUES ('43''0''北京XX区17''4''0');
    INSERT INTO `t_areainfo` VALUES ('44''0''北京XX区18''4''0');
    INSERT INTO `t_areainfo` VALUES ('45''0''北京XX区19''4''0');
    INSERT INTO `t_areainfo` VALUES ('46''0''xx省1''1''0');
    INSERT INTO `t_areainfo` VALUES ('47''0''xx省2''1''0');
    INSERT INTO `t_areainfo` VALUES ('48''0''xx省3''1''0');
    INSERT INTO `t_areainfo` VALUES ('49''0''xx省4''1''0');
    INSERT INTO `t_areainfo` VALUES ('50''0''xx省5''1''0');
    INSERT INTO `t_areainfo` VALUES ('51''0''xx省6''1''0');
    INSERT INTO `t_areainfo` VALUES ('52''0''xx省7''1''0');
    INSERT INTO `t_areainfo` VALUES ('53''0''xx省8''1''0');
    INSERT INTO `t_areainfo` VALUES ('54''0''xx省9''1''0');
    INSERT INTO `t_areainfo` VALUES ('55''0''xx省10''1''0');
    INSERT INTO `t_areainfo` VALUES ('56''0''xx省11''1''0');
    INSERT INTO `t_areainfo` VALUES ('57''0''xx省12''1''0');
    INSERT INTO `t_areainfo` VALUES ('58''0''xx省13''1''0');
    INSERT INTO `t_areainfo` VALUES ('59''0''xx省14''1''0');
    INSERT INTO `t_areainfo` VALUES ('60''0''xx省15''1''0');
    INSERT INTO `t_areainfo` VALUES ('61''0''xx省16''1''0');
    INSERT INTO `t_areainfo` VALUES ('62''0''xx省17''1''0');
    INSERT INTO `t_areainfo` VALUES ('63''0''xx省18''1''0');
    INSERT INTO `t_areainfo` VALUES ('64''0''xx省19''1''0');

    采用function获取所有子节点的id

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    --查询传入areaId及其以下所有子节点
    DROP FUNCTION IF EXISTS queryChildrenAreaInfo;
    CREATE FUNCTION `queryChildrenAreaInfo` (areaId INT)
    RETURNS VARCHAR(4000)
    BEGIN
    DECLARE sTemp VARCHAR(4000);
    DECLARE sTempChd VARCHAR(4000);
     
    SET sTemp = '$';
    SET sTempChd = cast(areaId as char);
     
    WHILE sTempChd is not NULL DO
    SET sTemp = CONCAT(sTemp,',',sTempChd);
    SELECT group_concat(id) INTO sTempChd FROM t_areainfo where FIND_IN_SET(parentId,sTempChd)>0;
    return sTemp;
     
    --调用方式
    select queryChildrenAreaInfo(1);
    select from t_areainfo where FIND_IN_SET(id, queryChildrenAreaInfo(1));

    https://zhidao.baidu.com/question/1303213320623933579.html

     https://www.iteye.com/problems/100720

  • 相关阅读:
    产品经理应该知道的那点事儿(1)
    C语言的前世今生
    “隔代教育的成功之道”新浪教育专家宋少卫做客西单图书大厦
    【9.21更新】跟踪报道TopLanguage关于《深入理解计算机系统(第2版)》一书翻译问题 的讨论
    中国要做物联网技术的强国,而非大国
    关于时钟芯片DS1302的问题
    stm32开发问题集锦
    keil 中使用c++的注意事项
    iar atof 问题
    IAR生成HEX文件
  • 原文地址:https://www.cnblogs.com/softidea/p/10271266.html
Copyright © 2020-2023  润新知