2009-02-19 15 views
9

Image Sie erstellen ein DB-Schema für eine Diskussionsrunde mit Threads. Gibt es eine effiziente Möglichkeit, eine korrekt sortierte Liste für einen bestimmten Thread auszuwählen? Der Code, den ich geschrieben habe, funktioniert, aber sortiert nicht so, wie ich es auch möchte.Rekursive SQL-CTEs und benutzerdefinierte Sortierreihenfolge

Angenommen, Sie haben diese Daten haben:

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

So ist die Struktur soll wie folgt aussehen:

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

Idealerweise in dem Code, wir die Ergebnismenge angezeigt werden soll in der Reihenfolge: 1, 2, 3, 5, 4
PROBLEM: Mit dem CTE ich es tatsächlich geschrieben wird zurückgegeben, wie: 1, 2, 4, 3, 5

Ich weiß, das wäre einfach zu gruppieren/bestellen mit LINQ, aber ich bin ungern, dies im Speicher zu tun. Es scheint die beste Lösung an dieser Stelle aber ...

Hier ist der CTE Ich bin derzeit mit:

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 

Jede Hilfe würde geschätzt; Vielen Dank!



Ich bin neu in SQL und hatte noch nicht von hierarchyid Datentyp gehört. Nachdem ich es von this comment gelesen habe, entschied ich, dass ich das in mein Design integrieren möchte. Ich werde heute Abend damit experimentieren und weitere Informationen veröffentlichen, wenn ich Erfolg habe.


aktualisieren
Erhaltenes Ergebnis aus meiner Beispieldaten, dance2die Vorschlag mit:

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

die sql Götter wachsen entrüstet von Ihren Ansprüchen – Shawn

Antwort

0

Hmmmm - Ich bin nicht sicher, ob Ihre Struktur am besten geeignet für dieses Problem ist. Von ganz oben kann ich mir sowieso nichts einfallen lassen, um die Daten so zu sortieren, wie Sie es in der obigen Abfrage haben wollen.

Das Beste, was ich mir vorstellen kann, ist, wenn Sie eine Elterntabelle haben, die Ihre Kommentare miteinander verbindet (zB eine Thementabelle). Wenn dies der Fall ist, sollten Sie Ihre Antworten einfach dazu hinzufügen können (Sie müssen natürlich die richtige Spalte hinzufügen), und dann können Sie nach topicID, Level sortieren, um die Sortierreihenfolge zu erhalten, nach der Sie suchen (oder welche anderen Informationen auch immer) Die Thementabelle stellt einen guten Wert für die Sortierung dar.

0

Erwägen Sie, die gesamte Hierarchie (mit Triggern, um sie zu aktualisieren, wenn sie sich ändert) in einem Feld zu speichern.

Dieses Feld in Ihrem Beispiel haben würde: 1,2 1.2.3 1.2.5 1,4

dann sortieren Sie müssen nur auf diesem Gebiet, versuchen Sie dies und sehen:

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

ja - das heißt materialisierte Pfad –

8

Ich bin sicher, dass Sie Liebe dies tun werden. I nach MSDN

Schauen Sie sich den Code unten und wie „CommentID“ herausfinden, was für „innerhalb der Partition einer Ergebnismenge Ranking“ ist, sortiert vor kurzem über Dense_Rank() Funktion.

Soweit ich verstehe, versuchen Sie, Ihre Ergebnismenge von ParentCommentID zu partitionieren.

Auf "dichterank" -Spalte achten.

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

Ergebnis unter

+0

Danke für den Vorschlag, ich habe versucht, dose_rank() zu arbeiten, um zunächst ohne Glück zu arbeiten. Ich habe Ihren Code auf meinen Beispieldaten abgefragt und es hat fast funktioniert. Eine Reihe war außer Betrieb. Ich werde die Daten oben veröffentlichen. –

1

Sie haben zu verwenden hierarchyid (SQL2008 nur) oder ein Bündel von string (oder Byte) Verkettung.