One table is storing a parent/ child relationship. I'm trying to get a return where the entries parent_id
returns the parents name child's name as a new column. The structure is as follows:
Table structure
label_template_category_id | name | parent_id | sort_order |
---|---|---|---|
5 | 'Christmas' | 0 | 4 |
7 | 'Father's Day' | 34 | 6 |
9 | 'Mother's Day' | 34 | 8 |
10 | 'New Baby' | 34 | 9 |
11 | 'New Home' | 34 | 10 |
13 | 'Thank You' | 0 | 12 |
14 | 'Wedding' | 0 | 13 |
15 | 'Business' | 0 | 0 |
16 | 'Valentine's Day' | 34 | 0 |
26 | 'New Year' | 0 | 0 |
28 | 'Retirement' | 0 | 0 |
29 | 'Sports Events/ Teams' | 0 | 0 |
34 | 'Celebration Days' | 0 | 0 |
Expected Results
label_template_category_id | name | parent_id | sort_order | group_name |
---|---|---|---|---|
5 | 'Christmas' | 0 | 4 | 'Christmas' |
7 | 'Father's Day' | 34 | 6 | 'Celebration Days > Father's Day' |
9 | 'Mother's Day' | 34 | 8 | 'Celebration Days > Mother's Day' |
10 | 'New Baby' | 34 | 9 | 'Celebration Days > New Baby' |
11 | 'New Home' | 34 | 10 | 'Celebration Days > New Home' |
13 | 'Thank You' | 0 | 12 | 'Thank You' |
14 | 'Wedding' | 0 | 13 | 'Wedding' |
15 | 'Business' | 0 | 0 | 'Business' |
16 | 'Valentine's Day' | 34 | 0 | 'Celebration Days > Valentine's Day' |
26 | 'New Year' | 0 | 0 | 'New Year' |
28 | 'Retirement' | 0 | 0 | 'Retirement' |
29 | 'Sports Events/ Teams' | 0 | 0 | 'Sports Events/ Teams' |
34 | 'Celebration Days' | 0 | 0 | 'Celebration Days' |
Using the following query I'm getting all the children returning on the parent instead of on the child like the expected results above.
SELECT
parent.label_template_category_id,
parent.name,
GROUP_CONCAT(child.name SEPARATOR ' > ') group_name
FROM label_template_category parent
LEFT JOIN label_template_category child
ON (child.parent_id = parent.label_template_category_id)
GROUP BY parent.label_template_category_id
ORDER BY group_name
Actual returned results
label_template_category_id | name | parent_id | sort_order | group_name |
---|---|---|---|---|
14 | 'Wedding' | 0 | 13 | |
15 | 'Business' | 0 | 0 | |
16 | 'Valentine's Day' | 34 | 0 | |
34 | 'Celebration Days' | 0 | 0 | 'Father's Day > Mother's Day > New Baby > New Home > Valentine's Day' |
I've created an SQL Fiddle for testing.
CodePudding user response:
I don't think you need a GROUP_CONCAT()
for this. And the order of LEFT JOIN
seems the other way around. Try this query:
SELECT
child.label_template_category_id,
child.name,
child.parent_id,
child.sort_order,
CASE WHEN parent.name IS NULL THEN child.name ELSE
CONCAT_WS(' > ',parent.name, child.name) END AS group_name
/*or maybe CONCAT_WS(' > ',parent.name, child.name) END AS group_name */
FROM label_template_category child
LEFT JOIN label_template_category parent
ON (child.parent_id = parent.label_template_category_id);
You need a CASE statement with CONCAT_WS() function. As you can see, I switched the LEFT JOIN
where the child
is set as reference instead. Then I'm doing a CASE
when the result from parent is NULL
it will return the data in column child.name
. Otherwise, if there's a match, it will concatenate parent.name
with child.name
.