MySQL parent children one query selection

I have a MySQL table with fields as below:

id            name             parent
1             Fruit             0
2             Meat              0
3             Orange            1
4             Beef              2

where parent field means the upper level id. For example Fruit id is 1, and Orange is one of the fruit so the parent is 1.

However I want to do an efficient MySQL query to fetch all records in the format parent->children->parent->children format. How can I do that?

The result record of the query should look like:

id            name             parent
1             Fruit             0
3             Orange            1
2             Meat              0
4             Beef              2

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You need a recursive join which mysql doesn’t support. The only thing you can do is determine the maximum level of depth (i your case it 1 since you have p->c) and with this you can determine the number of joins needed :

maximum level of depth = number of self-joins:

SELECT
    p.id as parent_id,
    p.name as parent_id,
    c1.id as child_id,
    c1.name as child_name
FROM 
    my_table p
LEFT JOIN my_table c1
    ON c1.parent = p.id
WHERE
    p.parent=0

For example if you max level of depth was 3 the you would need 3 self-joins:

SELECT
    p.id as parent_id,
    p.name as parent_id,
    c1.id as child_id_1,
    c1.name as child_name_1,
    c2.id as child_id_2,
    c2.name as child_name_2,
    c3.id as child_id_3,
    c3.name as child_name_3
FROM 
    my_table p
LEFT JOIN my_table c1
    ON c1.parent = p.id
LEFT JOIN my_table c2
    ON c2.parent = c1.id
LEFT JOIN my_table c3
    ON c3.parent = c2.id
WHERE
    p.parent=0

Method 2

How about this?

select * from foods
order by (case parent when 0 then id*1000 else parent*1000+id end), id

It’s not very nice, as it won’t work if you have more than 1000 foods with the same parent, but if you know that limit, it should do the trick.

Method 3

Here is another option to get the results you are looking for. You can group the parent and children together by the parent’s id and then indicate which record IS the parent (isparent) … like so: (this example assumes that a parent record has a NULL value for parent.. instead of 0.. but it can work with 0 too)

SELECT
    IFNULL(parent,id) AS parentid,
    IF(parent IS NULL,1,0) AS isparent,
    name
FROM my_table
ORDER BY
    parentid ASC, <- groups/orders all parentid's together
    isparent DESC, <- orders the parent first
    id DESC <- orders children by their id next

The rest should be easy to figure out, grouping your output, etc.

Method 4

You can use the below query with UNION:

SELECT ID, NAME, PARENT
FROM MY_TABLE AS A,
     MY_TABLE AS B
WHERE A.PARENT != 0 AND
      A.PARENT = B.ID
UNION
SELECT ID, NAME, PARENT
FROM MY_TABLE
WHERE PARENT == 0


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x