mysql tree structure, get all the child ID S according to pid

Go to the code directly (note that the ID here is self increasing, and the ID of the parent is smaller than that of the child)

Create a table (for example only, you can expand other fields by yourself):

CREATE TABLE `menu` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'menu id',
  `parent_id` int(11) DEFAULT NULL COMMENT 'Parent node id',
  `menu_name` varchar(128) DEFAULT NULL COMMENT 'Menu name',
  `menu_url` varchar(128) DEFAULT '' COMMENT 'Menu path',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Simulation data:

INSERT INTO `menu` VALUES ('0', null, 'Menu 0', 'Menu 0');
INSERT INTO `menu` VALUES ('1', '0', 'Menu 1', 'Menu 1');
INSERT INTO `menu` VALUES ('11', '1', 'Menu 11', 'Menu 11');
INSERT INTO `menu` VALUES ('12', '1', 'Menu 12', 'Menu 12');
INSERT INTO `menu` VALUES ('13', '1', 'Menu 13', 'Menu 13');
INSERT INTO `menu` VALUES ('111', '11', 'Menu 111', 'Menu 111');
INSERT INTO `menu` VALUES ('121', '12', 'Menu 121', 'Menu 121');
INSERT INTO `menu` VALUES ('122', '12', 'Menu 122', 'Menu 122');
INSERT INTO `menu` VALUES ('1221', '122', 'Menu 1221', 'Menu 1221');
INSERT INTO `menu` VALUES ('1222', '122', 'Menu 1222', 'Menu 1222');
INSERT INTO `menu` VALUES ('12211', '1222', 'Menu 12211', 'Menu 12211');

Query sql (@ pids: = parent ID of query):

SELECT
	c.id
FROM
	(
		SELECT
			a.id,
		IF (
			FIND_IN_SET(a.parent_id ,@pids) > 0,

		IF (
			length(@pids) - length(
				REPLACE (@pids, a.parent_id, '')
			) > 1,

		IF (
			length(@pids) - length(REPLACE(@pids, a.id, '')) > 1 ,@pids ,@pids := concat(@pids, ',', a.id)
		) ,@pids := concat(@pids, ',', a.id)
		),
		0
		) AS 'plist',

	IF (
		FIND_IN_SET(a.parent_id ,@pids) > 0,
		@pids,
		0
	) AS ischild
	FROM
		(
			SELECT
				r.id,
				r.parent_id
			FROM
				menu r
		) a,
		(SELECT @pids := 1) b
	) c
WHERE
	c.ischild != 0

Query results:

Note: if you want to add the parent ID to the top of the above SQL, add SELECT 1 FROM DUAL UNION ALL (1 is the parent ID)

Returns a field separated by commas (including the query's parent, @ pids: = query's parent ID):

SELECT
	*
FROM
	(
		SELECT
			c.plist
		FROM
			(
				SELECT
					a.id,

				IF (
					FIND_IN_SET(a.parent_id ,@pids) > 0,

				IF (
					length(@pids) - length(
						REPLACE (@pids, a.parent_id, '')
					) > 1,

				IF (
					length(@pids) - length(REPLACE(@pids, a.id, '')) > 1 ,@pids ,@pids := concat(@pids, ',', a.id)
				) ,@pids := concat(@pids, ',', a.id)
				),
				0
				) AS 'plist',

			IF (
				FIND_IN_SET(a.parent_id ,@pids) > 0,
				@pids,
				0
			) AS ischild
			FROM
				(
					SELECT
						r.id,
						r.parent_id
					FROM
						menu r
				) a,
				(SELECT @pids := 1) b
			) c
		WHERE
			c.ischild != 0
		ORDER BY
			c.id DESC
		LIMIT 0,
		1
	) d

Query results:

This sql is written on the basis of the following articles:
https://www.cnblogs.com/rainydayfmb/p/8028868.html

Keywords: SQL

Added by harryman100 on Mon, 23 Dec 2019 00:19:59 +0200