Database: sql recursion

mysql self association table, the following are examples of downward recursion and upward recursion.

1. Prepare for recursive query. If your table already exists, this step can be ignored.
  • Building tables
CREATE TABLE `wq_areainfo` (
 `id` int(11) NOT null AUTO_INCREMENT,
 `level` int(11) DEFAULT 0 ,
 `name` varchar(255) DEFAULT '0',
 `parentId` int(11) DEFAULT 0,
 `status` int(11) DEFAULT 0,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8;
  • Initialization data
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (1, 0, 'China', 0, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (2, 0, 'North China', 1, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (3, 0, 'Southern China District', 1, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (4, 0, 'Beijing', 2, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (5, 0, 'Haidian District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (6, 0, 'Fengtai District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (7, 0, 'Chaoyang District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (8, 0, 'Daxing District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (9, 0, 'Dongcheng District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (10, 0, 'Xicheng District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (11, 0, 'Chongwen District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (12, 0, 'Xuanwu District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (13, 0, 'Shijingshan District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (14, 0, 'Mentougou District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (15, 0, 'Fangshan District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (16, 0, 'Tongzhou District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (17, 0, 'Shunyi District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (18, 0, 'Changping District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (19, 0, 'Huairou District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (20, 0, 'Pinggu District', 4, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (46, 0, 'Jilin Province', 1, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (47, 0, 'Heilongjiang', 46, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (48, 0, 'Harbin', 46, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (49, 0, 'Dalian', 46, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (50, 0, 'Shenyang', 46, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (63, 0, 'Songyuan', 46, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (64, 0, 'Jilin City', 46, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (65, 0, 'Huludao', 46, 0);
INSERT INTO `t_areainfo` (`id`, `level`, `name`, `parentId`, `status`) VALUES (66, 0, 'Fuyu', 46, 0);
2. Recursively query all child nodes and child nodes under the current node
  • Using find in set() function and group concat() function to realize recursive query
    Where: group_concat(): multiple records compose one record; find_in_set (str, strlist): query specific columns in multiple records, str string to query, strlist field name parameters are separated by ",", such as (1,2,6,8):
DROP FUNCTION IF EXISTS queryChildren;
CREATE FUNCTION queryChildren(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;
END WHILE;
RETURN sTemp;
END;
  • Calling mode
SELECT queryChildren(1);


-Query all nodes with id "4"

SELECT * FROM wq_areainfo WHERE FIND_IN_SET(id,queryChildren(4));

3 recursively query all fathers and their fathers
DROP FUNCTION IF EXISTS queryParents;
CREATE FUNCTION queryParents(areaId INT)
RETURNS VARCHAR(4000)
BEGIN
DECLARE sTemp VARCHAR(4000);
DECLARE sTempChd VARCHAR(4000);

SET sTemp='$';
SET sTempChd = CAST(areaId AS CHAR);
SET sTemp = CONCAT(sTemp,',',sTempChd);

SELECT parentId INTO sTempChd FROM t_areainfo WHERE id = sTempChd;
WHILE sTempChd <> 0 DO
SET sTemp = CONCAT(sTemp,',',sTempChd);
SELECT parentId INTO sTempChd FROM t_areainfo WHERE id = sTempChd;
END WHILE;
RETURN sTemp;
END;
  • Query the father with id 47 and the father's father, and query the previous generation infinitely recursively.
    SELECT * from t_areainfo where FIND_IN_SET(id,queryParents(47));

Keywords: MySQL

Added by sford999 on Thu, 02 Jan 2020 02:39:13 +0200