Reputation: 2617
Trying to collect some heirarchical data to send out to a third party, and was directed to this post.
After attempting to tweak it to my use case on SQL Fiddle, the stored procedure keeps timing out.
So I tried it on locally twice (via PhpMyAdmin).
When I try to reload PMA in the browser after calling the stored procedure, I just get an eternal "waiting for response" spinner (more than 10 or 20 minutes).
I'm presuming there's something wrong with my SP code ???
CREATE TABLE foo
(`id` int, `name` varchar(100), `parentId` int, `path` varchar(100))
//
INSERT INTO foo (`id`, `name`, `parentId`, `path`)
VALUES (1, 'discrete', 0, NULL),
(2, 'res', 1, NULL),
(3, 'smt', 2, NULL),
(4, 'cap', 1, NULL),
(5, 'ind', 1, NULL),
(6, 'smt', 4, NULL),
(7, 'tant', 6, NULL),
(8, 'cer', 6, NULL)
//
CREATE PROCEDURE updatePath()
BEGIN
DECLARE cnt, n int;
SELECT COUNT(*) INTO n FROM foo WHERE parentId = 0;
UPDATE foo a, foo b SET a.path = b.name WHERE b.parentId IS NULL AND a.parentId = b.id;
SELECT count(*) INTO cnt FROM foo WHERE path IS NULL;
while cnt > n do
UPDATE foo a, foo b SET a.path = concat(b.path, '|', b.id) WHERE b.path IS NOT NULL AND a.parentId = b.id;
SELECT count(*) INTO cnt FROM foo WHERE path IS NULL;
end while;
END//
EDIT
Expected results:
VALUES (1, 'discrete', 0, '1'),
(2, 'res', 1, '1|2'),
(3, 'smt', 2, '1|2|3'),
(4, 'cap', 1, '1|4'),
(5, 'ind', 1, '1|5'),
(6, 'smt', 4, '1|4|6'),
(7, 'tant', 6, '1|4|6|7'),
(8, 'cer', 6, '1|4|6|8');
Upvotes: 2
Views: 148
Reputation: 2617
After a good nights sleep, I took @Drew's lead and I went through it one pc at a time.
Got it working. Here's where I'm leaving it:
CREATE TABLE foo
(`id` int, `name` varchar(100), `parentId` int, `path` varchar(100))
//
INSERT INTO foo
(`id`, `name`, `parentId`, `path`)
VALUES
(1, 'dscr', 0, NULL),
(2, 'res', 1, NULL),
(3, 'smt', 2, NULL),
(4, 'cap', 1, NULL),
(5, 'ind', 1, NULL),
(6, 'chp', 4, NULL),
(7, 'tant', 6, NULL),
(8, 'cer', 6, NULL)
//
CREATE PROCEDURE updatePath()
BEGIN
DECLARE cnt, n int;
SELECT COUNT(*) INTO n FROM foo WHERE parentId = 0; -- n is now 1
SELECT COUNT(*) INTO cnt FROM foo WHERE path IS NULL; -- cnt is now 8
UPDATE foo child, foo parent -- each child now has its parent and own ID's in the path
SET child.path = CONCAT(parent.id, '|', child.id)
WHERE parent.parentId = 0
AND child.parentId = parent.id;
WHILE cnt > n DO
UPDATE foo child, foo parent -- concat parent's path and own ID into each empty child's path
SET child.path = concat( parent.path,'|',child.id )
WHERE parent.path IS NOT NULL
AND child.parentId = parent.id;
SELECT COUNT(*) INTO cnt -- decrement cnt
FROM foo
WHERE path IS NULL;
END WHILE;
UPDATE foo -- set path for any top-level categories
SET path = id
WHERE path IS NULL;
END//
call updatePath()//
Feel free to critique.
Hope this helps someone else some time.
Upvotes: 1
Reputation: 1246
Are you trying to do a self-referencing join to create the hierarchy?
select a.name, parentName = b.name from foo a , outer join foo b on ( a.id = b.parentId )
Upvotes: 0