MySQL: how to query parent-child?

后端 未结 2 1103
难免孤独
难免孤独 2021-01-14 08:32

Assume the following table records:

TABLE: foo
==========================
| foo_id | foo_parent_id |
==========================
| 1      | NULL          |
|          


        
2条回答
  •  孤独总比滥情好
    2021-01-14 09:15

    I'd like to offer another approach at answering this question:

    SET @topN = 1;
    SELECT foo_id, foo_parent_id
    FROM (
        SELECT 
              f.foo_id
            , f.foo_parent_id
            , IFNULL(f.foo_parent_id, f.foo_id) AS grp_rank
            , CASE 
                WHEN f.foo_parent_id IS NULL 
                    THEN @topN:= 1 
                ELSE 
                    @topN:=@topN+1 
                END topN_rank
            , f_parent.foo_id AS f_parent_foo_id
        FROM 
            foo AS f
            RIGHT JOIN (
                SELECT foo_id 
                FROM foo 
                WHERE foo_parent_id IS NULL 
                ORDER BY foo_id LIMIT 10
            ) f_parent
            ON f_parent.foo_id = IFNULL(f.foo_parent_id, f.foo_id)
        ORDER BY grp_rank, f.foo_id
    ) AS foo_derived
    WHERE topN_rank <= 3
    

    General Notes:

    I want to get, say, the first 10 parent records <-- SUBQUERY "f_parent"

    followed by, say, the first 2 child records of that parent record. <-- topN <= 3 (PARENT + 2 CHILDREN)

    How it works:

    1. Create an extra column for foo_id to foo_parent_id integration grp_rank
    2. Join to a subquery pulling only the top 10 parents (assuming the order is by their foo_id values)
    3. Remember to sort by that extra column followed by foo_id for 'parent..followed by..first two children'
    4. Create another column than ranks the rows that will be sorted resetting via foo_parent encounters. NULL foo_parent_id resets the ranking. This new column topN_rank is impacted by the sorting.
    5. Nest that query to be able to derive topN_rank and to return only the needed columns.
    6. Filter by topN_rank column to get the top N rows for each group, prohibiting more than 3 per group.

提交回复
热议问题