2012-03-30 5 views
0

Meine Site verfügt über eine Messaging-Funktion, bei der ein Benutzer eine Nachricht senden kann. Die Nachrichten unterstützen das Threading - eine übergeordnete Nachricht kann eine beliebige Anzahl von untergeordneten Elementen haben, aber nur eine Ebene tief.SQL-Abfrage für Threaded-Nachrichten

Die Nachrichten-Tabelle sieht wie folgt aus:

Messages 
- Id (PK, Auto-increment int) 
- UserId (FK, Users.Id) 
- FromUserId (FK, Users.Id) 
- ParentMessageId (FK to Messages.Id) 
- MessageText (varchar 200) 

Ich mag würde Nachrichten mit jedem ‚Eltern‘ Nachricht von einer reduzierten Ansicht der Kinder-Nachrichten folgen auf einer Seite anzuzeigen.

Kann ich die GROUP BY-Klausel oder ein ähnliches Konstrukt verwenden, um übergeordnete Nachrichten und untergeordnete Nachrichten in einer einzigen Abfrage abzurufen? Im Moment erhalte ich nur übergeordnete Nachrichten, durchlaufe sie und führe eine weitere Abfrage durch, um alle zugehörigen untergeordneten Nachrichten zu erhalten.

Ich möchte Meldungen wie diese bekommen:

Parent1 
Child1 
Child2 
Child3 
Parent2 
Child1 
Parent3 
Child1 
Child2 
+0

Welches DBMS-System? MySQL? Orakel? –

+0

Ich benutze MySQL – Harper

Antwort

2

Sie eine temporäre ID verwenden können, um die Nachrichten zu bestellen. Wenn die Nachricht ein Elternteil ist, entspricht die temporäre ID der ID, andernfalls entspricht die temporäre ID der ParentMessageID. Dann brauchen Sie nur durch die temporäre ID bestellen

SELECT Messages.*, 
CASE WHEN ParentMessageId IS NULL THEN Id ELSE ParentMessageId END AS tempId 
FROM Messages 
ORDER BY tempId 

bearbeiten

Wenn Sie die ersten 10 Datensätze möchten Sie die Ids zuerst bekommen konnte und führen Sie dann die Abfrage

SELECT Messages.*, 
CASE WHEN ParentMessageId IS NULL THEN Id ELSE ParentMessageId END AS tempId 
FROM Messages 
WHERE Messages.tempId IN (SELECT Messages.Id 
         FROM Messages 
         WHERE ParentMessageId IS NULL 
         LIMIT 10 
         ORDER BY Messages.Id) 
ORDER BY tempId 

Diese So erhalten Sie nur die Nachrichten und die entsprechenden Kinder aus den ersten 10 Nachrichten.

+0

Ich möchte in der Lage sein, 10 "Eltern" Nachrichten auf einmal zu greifen, und dann alle ihre Kinder zu greifen, so dass ich übergeordnete Nachrichten in der Benutzeroberfläche durchblättern kann. – Harper

3

Versuchen Sie dies. Sie können den Bereich_ ersetzen, indem Sie eine Variable verwenden, die in Ihrem Front-End für die Paginierung vorhanden ist.

select child.MessageText from 
(select @i:[email protected]+1 as range_, id, MessageText from messages, (select @i:=0) k where ParentMessageId is null order by id asc) parent 
left outer join messages child on (parent.id = child.ParentMessageId or parent.id = child.id) 
where parent.range_ between 1 and 3; 
+1

Dies sollte die akzeptierte Antwort sein. Viel besser in Bezug auf die Leistung. – ZKK

Verwandte Themen