Reputation: 1305
There's a category hierarchy that looks like so:
--Level 1 category 1
|--Level 2 category 1
|--Level 3 category 1
|--Level 3 category 2
|--Level 3 category 3
|--Level 2 category 2
|--Level 3 category 4
|--Level 3 category 5
|--Level 3 category 6
--Level 1 category 2
|--Level 2 category 3
|--Level 3 category 7
How do I retrieve parents, siblings, and children of any particular category of any level?
For example, for "Level 3 category 5", the parent is "Level 2 category 2", siblings are "Level 3 category 4" and "Level 3 category 6", and no children. For "Level 2 category 3", the parent is "Level 1 category 2", siblings are "Level 2 category 2" and "Level 2 category 1", and a child in "Level 3 category 7";
I'm thinking of using WITH RECURSIVE query, but cannot figure it out how to do it.
Upvotes: 0
Views: 832
Reputation: 2479
You only need to use a recursive CTE because you want to get the siblings for the tree nodes, otherwise it's not necessary. A recursive CTE is used to generate level
values.
Here is what the query might look like
WITH RECURSIVE cte AS (
SELECT
*,
0 AS level
FROM categories
WHERE parent_id IS NULL
UNION ALL
SELECT
c.*,
cte.level + 1
FROM categories c
JOIN cte ON c.parent_id = cte.id
)
SELECT
c.id,
c.name,
c.parent_id,
cc.name AS parent_name,
GROUP_CONCAT(DISTINCT s.id) AS sinbling_ids,
GROUP_CONCAT(DISTINCT s.name) AS sibling_names,
GROUP_CONCAT(DISTINCT ch.id) AS children_ids,
GROUP_CONCAT(DISTINCT ch.name) AS childrent_names
FROM cte c
LEFT JOIN categories cc ON c.parent_id = cc.id
LEFT JOIN cte s ON c.level = s.level AND s.id != c.id
LEFT JOIN categories ch ON ch.parent_id = c.id
GROUP BY c.id, c.name, c.parent_id, cc.name
You can check a dbfiddle
Upvotes: 1