计算mysql中的第n级子元素
Posted
技术标签:
【中文标题】计算mysql中的第n级子元素【英文标题】:count nth level child element in mysql 【发布时间】:2015-11-18 06:22:21 【问题描述】:我无法计算每个根类别中的第 n 级子元素 我的类别视图,如
id parent_id name
1 0 Fashion
2 0 Beauty
3 0 Travel
4 0 Food
1006 1 Clothes
1009 1 Shoes
1011 1 Bags
1088 1009 Casual
1089 1009 Sport
2033 1088 Sneaker
2034 1088 Simple
---- ---- ------
---- ---- ------
我想从每个根元素的顶部到底部获取分层类别 id
喜欢时尚->衣服、鞋子、包包->休闲、运动->运动鞋、简约 1,1006,1009,1011,1088,1089,2033,2034
我在 mysql 中使用函数,但获取结果需要无限时间
CREATE DEFINER=`root`@`localhost` FUNCTION `GetAllNode`(GivenID INT) RETURNS text CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE rv,q,queue,queue_children TEXT;
DECLARE queue_length,front_id,pos INT;
SET rv = '';
SET queue = GivenID;
SET queue_length = 1;
WHILE queue_length > 0 DO
SET front_id = FORMAT(queue,0);
IF queue_length = 1 THEN
SET queue = '';
ELSE
SET pos = LOCATE(',',queue) + 1;
SET q = SUBSTR(queue,pos);
SET queue = q;
END IF;
SET queue_length = queue_length - 1;
SELECT IFNULL(qc,'') INTO queue_children
FROM (SELECT GROUP_CONCAT(CAST(id AS CHAR(50))) AS qc
FROM `categories` WHERE `parent_id` = front_id) A ;
IF LENGTH(queue_children) = 0 THEN
IF LENGTH(queue) = 0 THEN
SET queue_length = 0;
END IF;
ELSE
IF LENGTH(rv) = 0 THEN
SET rv = queue_children;
ELSE
SET rv = CONCAT(rv,',',queue_children);
END IF;
IF LENGTH(queue) = 0 THEN
SET queue = queue_children;
ELSE
SET queue = CONCAT(queue,',',queue_children);
END IF;
SET queue_length = LENGTH(queue) - LENGTH(REPLACE(queue,',','')) + 1;
END IF;
END WHILE;
RETURN rv;
END
从函数 GetAllNode() 获取结果的查询 选择编号 ,GetAllNode(id) FROM
categories
WHERE id=1
在表格结构和 数据
CREATE TABLE `categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(10) NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`color` varchar(10) DEFAULT '#efefef',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1084 DEFAULT CHARSET=latin1
INSERT INTO `categories` (`id`, `parent_id`, `name`, `color`, `created_at`, `updated_at`) VALUES
(1, 0, 'Fashion', '#60c6ce', '2015-10-21 13:47:54', '2015-10-21 16:47:54'),
(2, 0, 'Beauty', '#f29cb2', '2015-11-17 12:36:03', '2015-10-15 20:54:31'),
(3, 0, 'Travel', '#26a8e0', '2015-10-21 14:00:52', '2015-10-21 17:00:52'),
(4, 0, 'Food', '#f9ba3d', '2015-08-11 16:04:38', '2015-08-11 16:04:38'),
(5, 0, 'Wellness', '#86c87b', '2015-10-21 14:38:33', '2015-10-21 17:38:33'),
(6, 0, 'Inspiration', '#97249a', '2015-11-17 12:36:07', '2015-10-15 14:39:47'),
(7, 0, 'Culture', '#ff6c18', '2015-08-11 16:06:13', '2015-08-11 16:06:13'),
(1003, 0, 'Living', '#8e9dcd', '2015-10-21 14:34:21', '2015-10-21 17:34:21'),
(1006, 1, 'Clothes', '#60c6ce', '2015-10-21 13:51:15', '2015-10-21 16:51:15'),
(1009, 1, 'Shoes', '#60c6ce', '2015-10-21 13:52:38', '2015-10-21 16:52:38'),
(1011, 1, 'Bags', '#60c6ce', '2015-10-21 13:52:02', '2015-10-21 16:52:02'),
(1012, 1, 'Accessories', '#60c6ce', '2015-10-21 13:50:56', '2015-10-21 16:50:56'),
(1013, 1, 'Designers', '#60c6ce', '2015-10-21 13:52:21', '2015-10-21 16:52:21'),
(1014, 2, 'Make Up', '#f29cb2', '2015-10-15 14:50:15', '2015-10-15 14:50:15'),
(1015, 2, 'Skin', '#f29cb2', '2015-10-15 14:50:41', '2015-10-15 14:50:41'),
(1019, 0, 'Beauty', '#f29bb2', '2015-10-21 13:55:44', '2015-10-21 16:55:44'),
(1020, 1019, 'Make Up', '#f29bb2', '2015-10-21 16:56:23', '2015-10-21 16:56:23'),
(1021, 1019, 'Skin Care', '#f29bb2', '2015-10-21 14:15:35', '2015-10-21 17:15:35'),
(1022, 1019, 'Hair', '#f29bb2', '2015-10-21 16:58:40', '2015-10-21 16:58:40'),
(1023, 1019, 'Nails', '#f29bb2', '2015-10-21 16:59:03', '2015-10-21 16:59:03'),
(1024, 1019, 'Fragrance', '#f29bb2', '2015-10-21 16:59:40', '2015-10-21 16:59:40'),
(1025, 3, 'Things To Do', '#26a8e0', '2015-10-21 17:01:26', '2015-10-21 17:01:26'),
(1026, 3, 'Hotels', '#26a8e0', '2015-10-21 17:01:54', '2015-10-21 17:01:54'),
(1027, 3, 'Restaurants', '#26a8e0', '2015-10-21 17:02:21', '2015-10-21 17:02:21'),
(1028, 3, 'City Travel Guides', '#26a8e0', '2015-10-21 17:03:02', '2015-10-21 17:03:02'),
(1029, 3, 'Local - New York', '#26a8e0', '2015-10-21 17:27:39', '2015-10-21 17:27:39'),
(1030, 3, 'Local - London', '#26a8e0', '2015-10-21 17:28:00', '2015-10-21 17:28:00'),
(1031, 3, 'Local - Paris', '#26a8e0', '2015-10-21 14:28:38', '2015-10-21 17:28:38'),
(1032, 7, 'Movies', '#ff6c18', '2015-10-21 17:29:15', '2015-10-21 17:29:15'),
(1033, 7, 'Music', '#ff6c18', '2015-10-21 17:30:05', '2015-10-21 17:30:05'),
(1034, 7, 'TV', '#ff6c18', '2015-10-21 17:30:53', '2015-10-21 17:30:53'),
(1035, 7, 'Books', '#ff6c18', '2015-10-21 17:31:09', '2015-10-21 17:31:09'),
(1036, 7, 'Theatre', '#ff6c18', '2015-10-21 17:31:35', '2015-10-21 17:31:35'),
(1037, 7, 'Shows', '#ff6c18', '2015-10-21 17:32:11', '2015-10-21 17:32:11'),
(1038, 7, 'Art', '#ff6c18', '2015-10-21 17:32:28', '2015-10-21 17:32:28'),
(1039, 7, 'Events', '#ff6c18', '2015-10-21 17:32:44', '2015-10-21 17:32:44'),
(1040, 1, 'Celebrities', '#60c6ce', '2015-10-21 17:33:33', '2015-10-21 17:33:33'),
(1041, 1003, 'Home', '#8e9dcd', '2015-10-21 17:34:40', '2015-10-21 17:34:40'),
(1042, 1003, 'Decor', '#8e9dcd', '2015-10-21 17:35:28', '2015-10-21 17:35:28'),
(1043, 1003, 'Entertaining', '#8e9dcd', '2015-10-21 17:36:06', '2015-10-21 17:36:06');
【问题讨论】:
一个建议,在您的 create tabe 语句中,我认为最好将 ON UPDATE CURRENT 从 created_at 更改为 updated_at 【参考方案1】:你的函数有问题。您正在使用
SET front_id = FORMAT(queue,0);
这实际上在语言环境中格式化您的队列,我想它会执行以下操作:
FORMAT('1000',0) 输出=> 1,000
这会破坏你的功能。
只需将行 SET front_id = FORMAT(queue,0);
更改为 SET front_id = queue;
应该可以了!!
【讨论】:
感谢 Anshuman 运行良好,您为我节省了大量宝贵时间以上是关于计算mysql中的第n级子元素的主要内容,如果未能解决你的问题,请参考以下文章
js或jquery如何获取父级子级兄弟元素(包括祖级孙级等)