Oto jeden pomysł. Ale opiera się na wielu założeniach dotyczących sposobu konfiguracji danych. Ciągle rosnące identyfikatory w dół drzewa, tylko dwa poziomy itd.
SELECT f.foo_id,f.foo_parent_id FROM foo f
foo f
--podaj mi pierwszą X liczbę identyfikatorów_rodzica(To dobrze, po prostu dostosuj LIMIT 10, aby zmienić liczbę wyświetlanych poziomów nadrzędnych)
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
(Ta część jest trochę dziwaczna, ponieważ musisz umieścić ich coraz dłuższy ciąg, aby ominąć dwoje dzieci)
--to pierwsze dziecko, lub...
(f.foo_id in (select MIN(foo_id) from foo fc1 where fc1.foo_parent_id =f.foo_parent_id)
)
or
--to drugie dziecko, lub...
(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
--to rodzic
f.foo_parent_id is null
order by isnull(f.foo_parent_id,f.foo_id)*100 + f.foo_id
Więc to, co tutaj robimy, to w zasadzie porządkowanie według kolumny parent_id, a następnie kolumn podrzędnych pod nią z lekkim skrętem. Jeśli kolumna parentid ma wartość NULL, używamy rzeczywistego identyfikatora. Oznacza to, że na potrzeby zamówienia nasza tabela wygląda tak:
==============================================================================
| 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
----------------------------------------------------------------------
Następnie mnożymy tę kolumnę porządkowania *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
----------------------------------------------------------------------
i na koniec dodajemy do niego naszą kolumnę 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
----------------------------------------------------------------------
Teraz sortujemy tabelę według tej wirtualnej kolumny i...
==============================================================================
| 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
----------------------------------------------------------------------
Idziemy!