2016-04-19 16 views
0

ich ein Dokument Tisch habe - unterSQL Server: Gruppieren hierarchische Daten

In dieser Tabelle Definition siehe Wir haben ein Root-Dokument, das ein OriginalDocID von null hat

Jedes Mal, wenn eine Revision a gemacht neuer Eintrag mit den Eltern hinzugefügt documentID als OriginalDocID

Was ich suche nach Gruppe/partition alles um das Originaldokument, das OriginalDocID von null muss in der Lage zu tun ist,

Jedes Dokument kann mehrere Revisionen von einem Ursprungspunkt hat.

was bedeutet, wir

Doc Id 1 -> 2 -> 3 
     2 -> 8 -> 9 
     1 -> 4 -> 7 
     5 -> 10 

So haben kann, was ich hoffe, wieder zu sehen ist alle Zeilen mit dem Root-Dokument. hängten

Ich hoffe, das macht Sinn. Für das Leben von mir kann ich mich nicht um eine genügende Frage kümmern.

CREATE TABLE [dbo].[Document](
    [DocumentID] [int] IDENTITY(1,1) NOT NULL, 
    [DocumentName] [varchar](max) NOT NULL, 
    [ContentType] [varchar](50) NULL, 
    [DocumentText] [varchar](max) NULL, 
    [DateCreated] [datetime] NULL, 
    [DocumentTypeId] [int] NULL, 
    [Note] [varchar](8000) NULL, 
    [RefID] [int] NULL, 
    [Version] [int] NULL, 
    [Active] [bit] NULL, 
    [OriginalDocID] [int] NULL 
) 

Antwort

3

Sie müssen dafür einen rekursiven CTE verwenden. Das ist eine Abfrage, die sich auf sich selbst bezieht, so dass sie eine Hierarchie durchqueren und Informationen sammeln kann, während sie auf den Ebenen dieser Hierarchie nach unten (oder oben) arbeitet.

In Ihrem Fall so etwas wie:

WITH RECURSIVE docCTE AS 
(
    /* Recursive Seed */ 
    SELECT 
     cast(null as int) as parentdoc 
     documentID, 
     0 as depth, 
     documentid as originalDocument, 
     CAST(null as varchar(100) as docpath 
    FROM 
     dbo.document 
    Where originalDocID IS NULL 

    UNION ALL 

    /* Recursive Term */ 
    SELECT 
     docCTE.DocumentID as parentdoc, 
     document.documentID, 
     depth + 1 as depth, 
     docCTE.originalDocument, 
     docCTE.Path + '>' + document.documentID 
    FROM 
     docCTE 
     INNER JOIN dbo.document on doccte.document = document.originalDocID 
    WHERE 
     depth <= 15 /*Keep it from cycling in case of bad hierarchy*/ 

) 

SELECT * FROM docCTE; 

der rekursiven CTE besteht aus zwei Teilen.

  1. Die rekursive Seed, die wir verwenden, um die Abfrage zu treten. Dies sind alle Dokumentdatensätze, bei denen die Original-ID ungültig ist.

  2. Der rekursive Begriff, wo wir die Tabelle wieder auf den rekursiven CTE zur Gründung der Eltern/Kind-Beziehung verbinden.

In Ihrem Fall erfassen wir die documentid in der rekursiven Seed als originalDoc so dass wir nach unten durch die einzelnen Datensätze gefunden bringen können, wenn wir die Hierarchie der Dokumente beginnen überquert.

Diese können ein wenig überwältigend sein, wenn Sie beginnen, aber nachdem Sie es ein paar Mal geschrieben haben, ist es zweite Natur (und Sie werden die wirklich sehr hilfreich finden, wie Sie mehr dieser Art von Daten begegnen).

+0

Vielen Dank ein Dutzend. Das hilft mir bei der Frage und bei Rekursiven CTE's generell! – SCFi

+1

Großartig! Ich hoffe es funktioniert. Ich habe auch "Tiefe" und "Pfad" hinzugefügt, da Sie sich die Mühe machen, eine rekursive Abfrage zu schreiben. Sie könnten diese auch verwenden und den vollen Nutzen daraus ziehen. – JNevill