Announcement

Collapse
No announcement yet.

Gruppenverwaltung - Tabelle rekursiv durchlaufen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Gruppenverwaltung - Tabelle rekursiv durchlaufen

    Hallo,

    hab da ein SQL Problem bei dem ich einfach nich weiterkomme, hoffe ihr könnt mir helfen.

    Es geht dabei um eine Gruppenverwaltung. Ich will mit einer Abfrage, alle Untergruppen einer Gruppe rausfinden.
    Das ganze hat eine Baumstruktur und ich will mir alle Elemente eines Astes holen

    Gegeben ist folgende Tabelle
    <pre>
    Elterngruppe | Kindgruppe
    ---------------------------------
    1 | 2
    1 | 3
    1 | 4
    2 | 5
    2 | 6
    3 | 7
    3 | 8
    </pre>
    Wie kriege ich jetzt alle Kinder einer Elterngruppe mit einer SELECT Abfrage? Gibt es in SQL sowas wie while schleifen? Muß ich Unterabfragen benutzen?

    Bin für jede Hilfe dankbar...

    gruß,
    Markus

  • #2
    Hi Markus,

    sowie ich Dich verstanden habe ist das ganz einfach. Du brauchst Du eine WHERE-Klausel zu verwenden:

    SELECT Kindgruppe
    FROM Tabelle
    WHERE Elterngruppe = 1;

    Das Ergebnis:
    2,3,4

    War das die Frage?

    Viel Erfolg
    Frank

    P.S.: While kann es nicht geben da WHILE - Satzorientiert arbeitet, SQL ist aber Mengenorientiert

    Comment


    • #3
      ganz so einfach war die Abfrage dann doch nicht, ich wollte nämlich auch noch die Untergruppen der Untergruppen und deren Untergruppen usw...

      habe aber schon eine lösung gefunden, trotzdem danke..

      Comment


      • #4
        Tja, ohne weitere Angaben ist schwierig etwas geanaues zu sagen.
        m.E. geht das nur über mehrere Selects, deren Ergebnis man in temporären Tabellen zwsichenspeichert. Je nach DB-Typ und DB-Aufbau geht's eventuell auch in einme Select, belastet dann aber im Regelfall den Server ziemlich.
        Deshalb mach' ich so etwas grundsätzlich mit temporärern Tabellen...

        Grüße

        Joche

        Comment


        • #5
          Wenn Du die Lösung schon hattest ist okay. Ansonsten für Bäume etc. ist die Auflösung immer mit einem Self-Join als Ansatz nicht schlecht.

          SELECT *
          FROM Tabelle a, Tabelle b
          WHERE a.kindergruppe = b.elterngruppe

          Viele Grüße

          Fran

          Comment


          • #6
            Hallo,<br>

            mit diesem Statement bekommt man aber nur die direkt untergeordneten Knoten im Baum (nicht alle Knoten bis zu den Blättern), man muss also weiterhin rekursiv durch die Ergebnismenge dieser Abfrage laufen, oder?

            Gruß
            <i>Thomas</i&gt

            Comment


            • #7
              @Thomas:

              Es laufen alle Paarungen durch - also auch alle Knoten und Unterknoten und Blätter. Das Problem ist die Suche nach nur 1! Zweig. Da brauchst Du dann eine Rekursion, denn Du mußt ja immer den Bezug in die WHERE - Klausel einsetzten. Entweder machst Du das dann über das Front-End oder über ein Stored Proc.

              Am einfachsten wird so ein Baum jedoch, wenn man ihn anders als Markus aufbaut. Also nicht die Kinder einträgt sondern immer den nächst höheren (Vorgänger) als Bezug eingibt.

              Aber auf alle Fälle sind Bäume immer lustig...

              Viel Erfolg

              Fran

              Comment


              • #8
                Hi,
                Und wie lautet Deine Lösung?
                Ich stehe nämlivh vor einem ähnlichen Problem, bei dem der gefundene Datensatz erst den Wert für den nächsten zu findenden liefert. Mit while wäre das einfach, aber wie gesagt, while gibt es ja nich...

                Dank

                Comment


                • #9
                  Hi,

                  ich würde es so machen:

                  Ich habe 1 Tabelle mit z. B. Namen und 1 mit Angestellten und deren Vorgesetzen.

                  Tabell1 =
                  ID Name
                  1 - Meyer
                  2 - Müller
                  3 - Schulze
                  4 - Schmidt
                  5 - Krenz

                  Tabelle2 =
                  MIT - VOR
                  1 - <NULL>
                  2 - 1
                  3 - 1
                  4 - 2
                  5 - 2

                  So z. B. 1 ist Chef, dann gibt es 2 unter dem Chef und 4 + 5 sind ganz "unten".

                  Der Join für alle Paare sieht dann so aus:
                  select vor, mit from mit a inner join mit b on a.mit = b.vor

                  Ergebnis:
                  1 - 2
                  1 - 3
                  2 - 4
                  2 - 5

                  Jetzt mußt Du mit einer WHILE - Schleife in einer Prozedure der Datenbank oder Deinem Frontend eben Deinen gewünschten Zweig verfolgen. Entweder von oben nach unten oder von unten nach oben.

                  wenn du weißt wer der chef ist, ist das ganz einfach. Einfach ein WHERE vor = 1 eintragen und du bekommts nur die 2 und 3. Dann gehst Du weiter mit WHERE = 2 und danach WHERE = 3. Bei 3 wirst Du sehen: NIX mehr da...zweig zu ende.
                  bei 2 gehts weiter mit WHERE = 4 und WHERE = 5 und auch da is Feierabend.

                  Dann hast Du den ganzen Baum gezeichnet....

                  Viele Grüße
                  und viel Erfolg beim tüffeln.

                  Fran

                  Comment


                  • #10
                    Hallo.
                    Mit sowas hab ich mir auch schon den Kopf zerbrochen und bin zu einer denke ich ganz guten Lösung gekommen. Aufbau meiner Quelltabelle ist ähnlich.
                    Ausgabe wird in eine Tabelle geschrieben, die, wenn man sie dann aufruft eine Baumstruktur darstellt.

                    Hier mein Code:
                    <pre>

                    CREATE TABLE dbo.hlbBaumstruktur_Host
                    ([ID] int NOT NULL IDENTITY(1,1),
                    [Group] nvarchar(255),
                    Ebene nvarchar(50),
                    [Description] nvarchar(255))

                    SET NOCOUNT ON
                    DECLARE @current nvarchar(50)
                    SET @current = (SELECT Group_ID
                    FROM hlbGroup
                    INNER JOIN ESystem ON
                    hlbGroup.[System] = ESystem.[System]
                    WHERE GroupName = 'sys1' /*'ŸŸŸŸŸŸŸŸ'*/)

                    DECLARE @level int, @line nvarchar(50)
                    CREATE TABLE #tmpHostHiera ([Group] nvarchar(50), level int)
                    INSERT INTO #tmpHostHiera values (@current, 1)

                    SELECT @level = 1

                    WHILE @level &gt; 0
                    BEGIN
                    IF EXISTS (SELECT *
                    FROM #tmpHostHiera
                    WHERE level = @level)
                    BEGIN
                    SELECT @current = [Group]
                    FROM #tmpHostHiera
                    WHERE level = @level
                    SELECT @line = SPACE(@level - 1)+ @current
                    INSERT INTO hlbBaumstruktur_Host ([Group], Ebene)
                    SELECT SPACE(@level - 1)+ groupname, convert(nvarchar,@level)
                    FROM hlbGroup
                    WHERE @line = Group_ID
                    DELETE
                    FROM #tmpHostHiera
                    WHERE level = @level
                    AND [Group] = @current
                    INSERT #tmpHostHiera
                    SELECT ChildGroup_ID, @level + 1
                    FROM hlbHostGroup_Group
                    WHERE ParentGroup_ID = @current
                    IF @@ROWCOUNT &gt; 0
                    SELECT @level = @level + 1
                    END
                    ELSE
                    SELECT @level = @level - 1
                    END -- WHILE

                    DROP TABLE #tmpHostHiera
                    </pre>
                    Viel Spaß beim ausprobieren

                    Comment


                    • #11
                      <pre>Hallo,

                      ich habe ein ganz ähnliches Problem und komme aber mit euren Vorschlägen nicht ganz klar:

                      Also ich habe eine Vererbunghierachie:

                      Tabelle Classes mit (ClassID, MainClassID , Name)

                      Nun möchte ich alle Namen und ClassID's die Basisklasse einer speziellen Klasse sind auslesen.

                      Also z.B.

                      ClassID | MainClassID | Name
                      --------------------------------------
                      1 | null | BaseClass
                      2 | 1 | SubClass1
                      3 | 1 | SubClass2
                      4 | 2 | SubSubClass1
                      5 | 4 | UltraSubClass

                      Wenn ich jetzt UltraSubClass habe möchte ich also gern erfahren, dass diese Klasse von
                      1, 2 , 4 abgeleitet wurde.

                      Es sind auch Lösungen mit Stored Procedures willkommen.

                      Vielen Dank.
                      Kim</pre&gt

                      Comment


                      • #12
                        Hallo Kim,

                        ich kann nur eine Lösung für den ORACLE Server beisteuern, dort gibt es dafür eine ganz elegante Lösung über eine connect by Abfrage:<pre>
                        SELECT * FROM CLASS_TBL
                        CONNECT BY PRIOR MainClassID = ClassID
                        START WITH CLASS_ID = 5</pre>
                        Das Ergebnis dazu sollte dann so aussehen:<pre>
                        5 | 4 | UltraSubClass
                        4 | 2 | SubSubClass1
                        2 | 1 | SubClass1
                        1 | null| BaseClass</pre>

                        Gruß Fal
                        Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

                        Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

                        Comment


                        • #13
                          Danke.
                          Sowas wäre echt nett. Bisher löse ich das über eine StoredProcedure die mit einer While-Schleife durchgeht.

                          Gibt es sowas auch für SQL Server?

                          Comment

                          Working...
                          X