Announcement

Collapse
No announcement yet.

SQL-Unterabfrage "Verkettete Liste", harte Nuß!

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

  • SQL-Unterabfrage "Verkettete Liste", harte Nuß!

    Hallo,

    habe da ein logisches Prob was auch unter SQL gelöst werden können sollte. Es geht um Hauptbaugruppen, Unterbaugruppen, Baugruppen.
    Jeder Satz hat eine Baugr_ID und eine HptBaugr_id (gleiche Tabelle). Die Baugr_ID ist prim. Schlüssel.

    Baugr_ID HptBaugr_id <br>

    1 ******* 4 *****<br>
    2 ******* 4 *****<br>
    3 ******* 2 ***** <--- wie krieg ich den mit dazugezählt, bzw. separat ausgewiesen? <br>
    4 ******* 4 ***** <br>
    5 ******* 2 ***** <--- wie krieg ich den mit dazugezählt, bzw. separat ausgewiesen? <br>

    Nun möchte ich wissen, wieviel verschiedene Baugruppen beinhaltet die HptBaugr_id= 4. Bei
    Select count(*) from Tabelle where HptBaugr_id = 4
    kommt als Antwort z.B. 7. Diese Antwort berücksichtigt aber nur die direkten Unterbaugruppen. Wenn diese nochmal weiterverzweigen bekomme ich die so nicht zu fassen. Zumal es ja beliebig tiefe Verzweigungen dieser verketteten Liste geben kann. Wie bekommt man die zu fassen, separat ausgewiesen? Geht das in SQL überhaupt?

    Schön wäre ein Ergebnis wie:

    HptBaugr_id Ebene_1 Ebene_2 Ebene_3 Ebene_4 Ebene_n <br>

    4 ********** 7******* 2******** 8******* 0****** 0 <br>
    2 ********** 3******* 17******* 4******* 2****** 5 <br>

    Oder bleibt da nur das Abzählen per Schleife mit "while true".
    Gibt es in SQL eine Lösung für verkettete Listen? Tks.

    Viele Grüße, Kde

  • #2
    <br>Hi,...
    <br>
    <br>dieses Problem ist mit einer Stored Peocedure lösbar!
    Wenn du mit der Alternativen "while true" ein ClientScript meinst wäre es sinnvoller diesen Code auf dem Server als Stored Procedure zu implementieren.
    <br>
    <br>Welcher SQL Server wird eingesetzt?
    <br>Bei Oracle soll man so etwas auch mit spezielen Select Statements machen können. Hier im Forum mal nach "Baum" (Baumstruktur) suchen ggf. kannst du da was finden (wenn Stored Procedure unerwünscht sind).
    <br>
    <br>mfg
    <br>P

    Comment


    • #3
      Hi,

      die Lösungskonzepte die ich bisher habe sind alle nicht optimal und bedingen immer noch manuelles eingreifen, von daher besten Dank für jeden Vorschlag. <p>
      Verwendeter Server ist MS-Sql-7. Gegen eine Stored Procedure, wie lösbar, hätte ich nichts. Wie sollte ich da am besten vorgehen? Werde zusätzlich mal nach Baum suchen.

      Freundliche Grüße, Kd

      Comment


      • #4
        <br>Hi,...
        <br>dummer weise habe ich im Moment keinen SQL Code zur Hand, der so etwas machen kann.
        <br>
        <br>Ich habe nur Delphi Code, der so etwas macht. Bin jedoch leider noch nicht dazu gekommen, diesen Code auf SQL umzusetzten. Dieser Code gibt jedoch die Richtung an. Mit diesem Code wird eine TreeView Komponente gefüllt, bei einer Stored Proc mußt du jedoch die Werte in eine Temporäre Tabelle zwischen speichern und diese nach getaner arbeit ausgeben. Die Funktion ist rekursiv man kann auch überlegen, ob man dies nicht doch lieber iterativ löst (wer weiß ob der SQL Server rekursionen ohne weiteres annimmt).
        <br>
        <br>Ich hoffe das hilft dir weiter.
        <br>
        <br>Function TfrmArtikelliste.FillTreeView(InKat, InABG : Integer; OldNode : TTreeNode) : Boolean;
        <br>Var
        <br> Myqry : TADODataSet;
        <br> IstKat, IstABG : Integer;
        <br> NewNode : TTreeNode;
        <br>Begin
        <br> Myqry := TAdoDataSet.Create(self);
        <br> Myqry.Connection := DM1.cnnMain;
        <br> Myqry.CommandText := 'SELECT * From X'
        <br> 'WHERE ' +
        <br> 'tbl_KatABG.KatABG_InKat = ' + IntToStr(InKat) +
        <br> ' AND ' +
        <br> 'tbl_KatABG.KatABG_InABG = ' + IntToStr(InABG);
        <br> Myqry.Open;
        <br> while Not Myqry.Eof do
        <br> Begin
        <br> IstKat := Myqry.FieldByName('KatABG_IstKat').asInteger;
        <br> IstABG := Myqry.FieldByName('KatABG_IstABG').asInteger;
        <br> If IstKat <> -1 Then
        <br> Begin
        <br> NewNode := TreeView1.Items.AddChild(OldNode,Myqry.FieldByName ('Kat_Bez').asString);
        <br> //Bilder zuweisen
        <br> NewNode.ImageIndex := 0;
        <br> NewNode.SelectedIndex := 0;
        <br> End
        <br> Else If IstABG <> -1 Then
        <br> Begin
        <br> If Myqry.FieldByName('ABG_BezK').asString = '' Then
        <br> ShowMessage(Myqry.FieldByName('KatABG_IstABG').asS tring);
        <br> NewNode := TreeView1.Items.AddChild(OldNode,Myqry.FieldByName ('ABG_BezK').asString);
        <br> //Bilder zuweisen
        <br> NewNode.ImageIndex := -1; //erst einmal -1 später kommt hier <br>noch ein richtiger Index hin
        <br> NewNode.SelectedIndex := -1;
        <br> End;
        <br>
        <br> New(ID);
        <br> ****************Hier mußt du die Werte in eine Temporäre Tabelle schreibn*************
        <br> ID^.KatABG_ID := Myqry.FieldByName('KatABG_ID').asInteger;
        <br> ID^.IstKat := IstKat;
        <br> ID^.IstABG := IstABG;
        <br> ID^.InKat := Myqry.FieldByName('KatABG_InKat').asInteger;
        <br> ID^.InABG := Myqry.FieldByName('KatABG_InABG').asInteger;
        <br> NewNode.Data := ID;
        <br>
        <br> FillTreeView(IstKat, IstABG, NewNode);
        <br> pbABG.Position := pbABG.Position + 1;
        <br> Myqry.Next;
        <br> End;
        <br> Myqry.Close;
        <br> Myqry.Free;
        <br>End;
        <br>
        <br>
        <br>mfg
        <br>p

        Comment

        Working...
        X