2011-11-05 14 views
10

Próbuję napisać moje zapytanie SQL Server 2008 w taki sposób, żebym mógł w razie potrzeby przeliczyć swoje nagłówki wyjściowe i wyjściowe. Zrobiłem te rzeczy w niewłaściwy sposób wiele razy i kazałem ColdFusion wykonać ciężką pracę na stronie, ale trzeba to zrobić w SQL Server.Jak mogę zamówić przez rodzica, a następnie dziecko?

FeatureID ParentID Feature 
-------------------------- 
1   0  Apple  
2   0  Boy 
3   2  Charles 
4   1  Daddy 
5   2  Envelope 
6   1  Frankfurter 

chcę mój resultset kwerendy wyglądać następująco:

FeatureID ParentID Feature 
-------------------------- 
1   0  Apple  
4   1  Daddy 
6   1  Frankfurter 
2   0  Boy 
3   2  Charles 
5   2  Envelope 

Jeśli ParentID wynosi 0, oznacza to, że jest jednym z głównych kategorii. Jeśli ParentID jest większy od 0, oznacza to, że jest to kategoria podrzędna, dziecko rodzica.

Tak więc rodzice muszą otrzymać polecenie A - Z, a dzieci należy zamówić z A-Z.

Czy pomożesz mi to uporządkować prawidłowo?

SELECT FeatureID, ParentID, Feature 
FROM Features 
ORDER BY 
+0

Więc dlaczego Chłopiec parentId 0 klasyfikowane poniżej Frankfurtera z parentId 1? – Andomar

+0

Ponieważ chcę wypisać rodzic, a następnie jego dzieci, a następnie następny rodzic, a następnie jego dzieci. –

+1

wypróbuj ten prostszy sposób: http://stackoverflow.com/questions/13382380/mysql-order-by-parent-and-child – Otak

Odpowiedz

9

Z Twojego komentarza, jeśli wiesz, że istnieją tylko dwa poziomy, nie jest to łatwe rozwiązanie:

select * 
from @Features feat 
order by 
     case 
     when ParentID = 0 
     then Feature 
     else (
       select Feature 
       from @Features parent 
       where parent.FeatureID = feat.ParentID 
       ) 
     end 
,  case when ParentID = 0 then 1 end desc 
,  Feature 
  1. Sortuj według nazwy elementu głównego: do korzeni, to kolumna Cecha. Dla dzieci spójrz na nazwę root'a z podzapytaniem.
  2. Sortuj korzeń na najwyższym
  3. Sortuj dzieci wg nazwy

Example at SE Data.

+0

Jeepers !!! To dużo kodu na coś, co wydaje się być dużo prostsze. Twój przykład wydaje się działać dobrze. Jest to bardziej uciążliwe, niż robi to w inny sposób. –

+0

Tak, droga do skomplikowania kodu produkcyjnego. Miałem nadzieję, że ktoś inny postawi prostsze rozwiązanie. Zauważ, że możesz znacznie uprościć kod, gdybyś był ograniczony do określonej głębokości, powiedzmy maksymalnie 2 węzły między korzeniem a liściem. – Andomar

+0

W rzeczywistości będą tylko dwa poziomy, rodzic i dziecko. Ther nie będzie dziadkami ani wnukami. –

6

dla mysql, można spróbować: (pod warunkiem ParentID dziecka jest twoim parentId za FeatureID)

SELECT FeatureID, ParentID, Feature 
FROM Features 
ORDER BY case when ParentID=0 then FeatureID else ParentID end * 1000 + FeatureID ASC 
+0

+1 To działa ładnie tak długo, jak tabela jest w porządku alfabetycznym, i nie masz więcej niż 999 wierszy – Andomar

+1

Nie powinno to być po prostu "ZAMÓW przez przypadek, gdy ParentID = 0 THEN FeatureID ELSE ParentID END ASC, FeatureID ASC zamiast tego? Ponieważ wtedy nadal będzie używać indeksów, a także nie będzie ograniczony do 999 rekordów. Ale tak, to się nie powiedzie, jeśli masz '(7, 8, 'bar')' i '(8, 0, 'foo')', ("WYBIERZ LICZBĘ (1) Z funkcji GDZIE IDENTYFIKATORA Seph

Powiązane problemy