Hier is een idee. Maar het is gebaseerd op veel aannames over de manier waarop uw gegevens zijn ingesteld. Steeds meer ID's in de boom, slechts twee niveaus, enz.
SELECT f.foo_id,f.foo_parent_id FROM foo f
foo f
--geef me het hoogste X-nummer van parent_ids(Dit is goed, je past gewoon de LIMIT 10 aan om het aantal te tonen ouderniveaus te variëren)
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
(Dit deel is nogal hacky, omdat je er een steeds langere reeks van moet plaatsen om voorbij twee kinderen te komen)
--het is het eerste kind, of...
(f.foo_id in (select MIN(foo_id) from foo fc1 where fc1.foo_parent_id =f.foo_parent_id)
)
or
--het is het tweede kind, of...
(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
--het is de ouder
f.foo_parent_id is null
order by isnull(f.foo_parent_id,f.foo_id)*100 + f.foo_id
Dus wat we hier doen, is in feite ordenen op de kolom parent_id en vervolgens de onderliggende kolommen met een kleine draai. Als de parentid-kolom NULL is, gebruiken we de werkelijke ID. Dit betekent dat voor besteldoeleinden onze tafel er als volgt uitziet:
==============================================================================
| 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
----------------------------------------------------------------------
Dan vermenigvuldigen we die bestelkolom *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
----------------------------------------------------------------------
en als laatste voegen we onze foo_id-kolom eraan toe
==============================================================================
| 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
----------------------------------------------------------------------
Nu rangschikken we de tabel op die virtuele kolom en...
==============================================================================
| 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
----------------------------------------------------------------------
Daar gaan we!