Ето една идея. Но се основава на много предположения за начина, по който данните ви са настроени. Постоянно нарастващи идентификатори надолу по дървото, само две нива и т.н.
SELECT f.foo_id,f.foo_parent_id FROM foo f
foo f
--дайте ми най-горния X брой на parent_ids(Това е добре, просто коригирате LIMIT 10, за да променяте броя на родителските нива за показване)
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
(Тази част е доста хакерска, тъй като трябва да поставите все по-дълъг низ от тях, за да преминете през две деца)
--това е първо дете или...
(f.foo_id in (select MIN(foo_id) from foo fc1 where fc1.foo_parent_id =f.foo_parent_id)
)
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
--това е родителят
f.foo_parent_id is null
order by isnull(f.foo_parent_id,f.foo_id)*100 + f.foo_id
Така че това, което правим тук, е основно подреждане по колоната parent_id и след това дъщерните колони под нея с леко завъртане. Ако колоната parentid е NULL, тогава използваме действителния ID. Това означава, че за целите на поръчката нашата таблица изглежда така:
==============================================================================
| 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
----------------------------------------------------------------------
След това умножаваме тази колона за подреждане *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
----------------------------------------------------------------------
и накрая добавяме нашата колона 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
----------------------------------------------------------------------
Сега подреждаме таблицата по тази виртуална колона и...
==============================================================================
| 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
----------------------------------------------------------------------
Ето го!