MySQL: how to query parent-child?

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

Assume the following table records:

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


        
2条回答
  •  猫巷女王i
    2021-01-14 09:25

    Here's one idea. But it's based on lots of assumptions about the way your data is setup. Ever increasing IDs down the tree, only two levels, etc.

    SELECT f.foo_id,f.foo_parent_id FROM foo f
    foo f
    

    --give me the top X number of parent_ids (This is good, you just adjust the LIMIT 10 to vary the number of parent levels to show)

    INNER JOIN 
    (select foo_id from foo where foo_parent_id is null order by foo_parent_id 
    LIMIT 10
    ) top_foo_parent
          on isnull(f.foo_parent_id,f.foo_id) = top_foo_parent.foo_id
    WHERE
    

    (This part is kind of hacky, as you have to put an ever longer string of these to get past two children)

    --it's the first child, or...

    (f.foo_id in (select MIN(foo_id) from foo fc1 where fc1.foo_parent_id =f.foo_parent_id)
     )
     or
    

    --it's the second child, or...

    (f.foo_id in (select MIN(foo_id) from foo fc1 where fc1.foo_parent_id =f.foo_parent_id  and fc1.foo_id not in (select MIN(foo_id) from foo fc2 where fc2.foo_parent_id=f.foo_parent_id))
     )
     or 
    

    --it's the parent

     f.foo_parent_id is null
    order by isnull(f.foo_parent_id,f.foo_id)*100 + f.foo_id
    

    So what we're doing here is basically ordering by the parent_id column and then the child columns underneath it with a slight twist. If the parentid column is NULL then we use the actual ID. This means that for ordering purposes our table looks like this:

    ==============================================================================
    | foo_id | foo_parent_id |   isnull(f.foo_parent_id,f.foo_id)
    ==============================================================================
    | 1      | NULL           |         (1)
    | 2      | NULL           |         (2)
    | 3      |  1             |         1
    | 4      |  2             |         2
    | 5      |  1             |         1
    | 7      |  2             |         2
    ----------------------------------------------------------------------
    

    Then we multiply that ordering column *100

    ==============================================================================
    | foo_id | foo_parent_id |   isnull(f.foo_parent_id,f.foo_id)*100
    ==============================================================================
    | 1      | NULL           |         100
    | 2      | NULL           |         200
    | 3      |  1             |         100
    | 4      |  2             |         200
    | 5      |  1             |         100
    | 7      |  2             |         200
    ----------------------------------------------------------------------
    

    and lastly we add our foo_id column to it

    ==============================================================================
    | foo_id | foo_parent_id |   isnull(f.foo_parent_id,f.foo_id)*100 + foo_id
    ==============================================================================
    | 1      | NULL           |         101
    | 2      | NULL           |         202
    | 3      |  1             |         103
    | 4      |  2             |         204
    | 5      |  1             |         105
    | 7      |  2             |         207
    ----------------------------------------------------------------------
    

    Now we order the table by that virtual column and...

    ==============================================================================
    | foo_id | foo_parent_id |   ORDER BY isnull(f.foo_parent_id,f.foo_id)*100 + foo_id
    ==============================================================================
    | 1      | NULL           |         101
    | 3      |  1             |         103
    | 5      |  1             |         105
    | 2      | NULL           |         202    
    | 4      |  2             |         204
    | 7      |  2             |         207
    ----------------------------------------------------------------------
    

    There we go!

提交回复
热议问题