See this SQL Fiddle. It generates a list with the id-s of all descendants of the element with id 10
.
If I add an INDEX
on the column ParentId
, the result set changes. Now only the children of the root element are included, and not all the descendants. See this SQL Fiddle.
Is this a bug in MySQL? I don't think adding an INDEX
should ever change the result set of a query.
If I change the id of the root element, so that it is smaller than the id of the other elements, it works again even with the INDEX
. See this SQL Fiddle.
The query, which generates a list with the id-s of all descendants of an element x
, works like this:
- Concatenate the id-s of all elements whose parent is
x
. - Concatenate the id-s of all elements whose parent is in the list generated in the previous step.
- Repeat step 2 until there are no more elements to add.
- Concatenate all the lists into one long list of id-s.
Here is the query, where <id>
is the id of the element x
:
SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM (
SELECT @Ids := (
SELECT GROUP_CONCAT(`Id` SEPARATOR ',')
FROM `Table`
WHERE FIND_IN_SET(`ParentId`, @Ids)
) Level
FROM `Table`
JOIN (SELECT @Ids := <id>) temp1
WHERE FIND_IN_SET(`ParentId`, @Ids)
) temp2
For completion, here is the database schema that gives an incorrect result set:
CREATE TABLE `Table` (
`Id` int(8),
`ParentId` int(8),
INDEX(`ParentId`)
);
INSERT INTO `Table` (Id, ParentId)
VALUES
(10, NULL),
(2, 10),
(3, 2),
(4, 2),
(5, 10);