Ecco un'idea. Ma si basa su molte ipotesi sul modo in cui i tuoi dati sono impostati. ID in continuo aumento lungo l'albero, solo due livelli, ecc.
SELECT f.foo_id,f.foo_parent_id FROM foo f
foo f
--dammi il numero X superiore di parent_ids(Va bene, basta regolare il LIMIT 10 per variare il numero di livelli genitore da mostrare)
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
(Questa parte è un po' complicata, perché devi metterne una serie sempre più lunga per superare due bambini)
--è il primo figlio, o...
(f.foo_id in (select MIN(foo_id) from foo fc1 where fc1.foo_parent_id =f.foo_parent_id)
)
or
--è il secondo figlio, o...
(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
--è il genitore
f.foo_parent_id is null
order by isnull(f.foo_parent_id,f.foo_id)*100 + f.foo_id
Quindi quello che stiamo facendo qui è fondamentalmente ordinare in base alla colonna parent_id e quindi alle colonne figlio sotto di essa con una leggera svolta. Se la colonna parent è NULL, utilizziamo l'ID effettivo. Ciò significa che ai fini dell'ordinazione la nostra tabella si presenta così:
==============================================================================
| 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
----------------------------------------------------------------------
Quindi moltiplichiamo quella colonna di ordinamento *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
----------------------------------------------------------------------
e infine aggiungiamo la nostra colonna foo_id
==============================================================================
| 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
----------------------------------------------------------------------
Ora ordiniamo la tabella in base a quella colonna virtuale e...
==============================================================================
| 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
----------------------------------------------------------------------
Eccoci!