2009-02-19 15 views
9

Obraz, który tworzysz, jest schematem DB dla nagłownego forum dyskusyjnego. Czy istnieje skuteczny sposób wyboru prawidłowo posortowanej listy dla danego wątku? Kod, który napisałem, działa, ale nie sortuje tak, jakbym chciał.Rekurencyjne zapytania SQL CTE i niestandardowe sortowanie sortów

Powiedzmy masz te dane:

ID | ParentID 
----------------- 
1 | null 
2 | 1 
3 | 2 
4 | 1 
5 | 3

więc struktura ma wyglądać następująco:

1 
|- 2 
| |- 3 
| | |- 5 
|- 4

Idealnie, w kodzie, chcemy wynik pojawiać się w następująca kolejność: 1, 2, 3, 5, 4
PROBLEM: Za pomocą CTE napisałem, że jest on zwracany jako: 1, 2, 4, 3, 5

Wiem, że łatwo byłoby pogrupować/zamówić za pomocą LINQ, ale niechętnie robię to w pamięci. Wydaje się, że najlepszym rozwiązaniem w tym momencie mimo ...

Oto CTE Obecnie używam:

with Replies as ( 
    select c.CommentID, c.ParentCommentID 1 as Level 
     from Comment c 
     where ParentCommentID is null and CommentID = @ParentCommentID 

    union all 

    select c.CommentID, c.ParentCommentID, r.Level + 1 as Level 
     from Comment c 
     inner join Replies r on c.ParentCommentID = r.CommentID 
) 

select * from Replies 

Każda pomoc będzie mile widziane; Dzięki!


Jestem nowy w SQL i wcześniej nie słyszałem o typie danych hierarchyid. Po przeczytaniu o nim z this comment zdecydowałem, że mogę włączyć to do mojego projektu. Będę eksperymentować z tym wieczorem i opublikuję więcej informacji, jeśli osiągnę sukces.


Aktualizacja
Zwracany wynik z moich przykładowych danych, stosując sugestię dance2die za:

ID | ParentID | Level | DenseRank 
------------------------------------- 
15  NULL   1   1 
20  15   2   1 
21  20   3   1 
17  22   3   1 
22  15   2   2 
31  15   2   3 
32  15   2   4 
33  15   2   5 
34  15   2   6 
35  15   2   7 
36  15   2   8
+0

bogowie sq wyrosli oburzeni z twoich roszczeń – Shawn

Odpowiedz

0

Hmmmm - Nie jestem pewien, czy struktura jest najlepiej nadaje się do tego problemu. Poza tym nie mogę w ogóle myśleć o sortowaniu danych według powyższego zapytania.

Najlepsze, co mogę wymyślić, to jeśli masz tabelę nadrzędną, która wiąże twoje komentarze razem (np. Tabela tematów). Jeśli to zrobisz, powinieneś być w stanie po prostu przyłączyć się do odpowiedzi na to (oczywiście musisz dołączyć poprawną kolumnę w sposób oczywisty), a następnie możesz sortować według ID tematu, Poziom, aby uzyskać porządek sortowania, którego szukasz (lub dowolne inne informacje na temat tabela tematów przedstawia dobrą wartość do sortowania).

0

Należy rozważyć przechowywanie całej hierarchii (z wyzwalaczami, aby ją zaktualizować, jeśli ulegnie ona zmianie) w polu.

To pole w swoim przykładzie musiałby: 1,2 1.2.3 1.2.5 1,4

wtedy po prostu trzeba rozwiązać w tej dziedzinie, spróbować i zobaczyć:

create table #temp (test varchar (10)) 
insert into #temp (test) 
select '1' 
union select '1.2' 
union select '1.2.3' 
union select '1.2.5' 
union select '1.4' 
select * from #temp order by test asc 
+0

tak - to się nazywa zmaterializowana ścieżka –

8

Jestem pewien, że będzie to miłość tego. Niedawno Sprawdzaj Dense_Rank() funkcję, która jest na „Ranking w rozbicie zbioru wynikowego” według MSDN

Sprawdź poniżej kodu i jak „CommentID” jest posortowana.

O ile rozumiem, próbujesz podzielić swój zestaw wyników według ParentCommentID.

Zwróć uwagę na kolumnę "denserank".

with Replies (CommentID, ParentCommentID, Level) as 
(
     select c.CommentID, c.ParentCommentID, 1 as Level 
     from Comment c 
     where ParentCommentID is null and CommentID = 1 

     union all 

     select c.CommentID, c.ParentCommentID, r.Level + 1 as Level 
     from Comment c 
       inner join Replies r on c.ParentCommentID = r.CommentID 
) 
select *, 
     denserank = dense_rank() over (partition by ParentCommentID order by CommentID) 
from Replies 
order by denserank 

alt text

Wynik poniżej

+0

Dzięki za sugestię, próbowałem dostać dense_rank() do pracy na początku bez powodzenia. Przeszukałem twój kod na moich przykładowych danych i działało ... prawie. Jeden rząd był nieczynny. Opublikuję powyższe dane. –

1

Musisz użyć hierarchyid (tylko sql2008) lub pęczek strun (lub bajt) konkatenacji.