Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen (https://www.delphipraxis.net/155671-%5Bsql%5D-kaskadierende-eltern-kind-beziehung-selber-tabelle-aufloesen.html)

Medium 3. Nov 2010 15:31

Datenbank: MySQL • Version: 5.1.11 • Zugriff über: UniDAC

[SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
Ahoi!

Ich habe hier eine Tabelle der Struktur (ID, Text, ParentID).

Ich möchte jetzt gerne in einem Select ein Feld zusammen setzen, dass alle "Text" hintereinander enthält bis ein ParentID=NULL erreicht ist, und zwar beginnend mit dem letzten Parent. Folgende hypothetische Tabelle:
Code:
ID  Text    ParentID
----------------------------
0   "Hallo" NULL
1   "Satz"  2
2   "ein"   4
3   "ich"   0
4   "bin"   3
Dann brauche ich in meiner Ergebnismenge einen Datensatz
Code:
ID  Text
-----------------------------
1   "Hallo ich bin ein Satz"
Die Ergebnismenge besteht dabei jedoch nicht nur aus einem einzelnen Datensatz, sondern derer Kaskaden können in der Basistabelle mehrfach sein, und auch unterschiedlich tief.
Es gibt mehr Felder als nur diese drei, und die anderen Felder sollen die Werte des gerade aufgelösten Datensatzes beibehalten. Es soll zudem jeder Datensatz aufgelöst werden. Beispiel:


Code:
ID  Text          ParentID  Info
-----------------------------------------
0   "Firma A"     NULL      "foo"
1   "Firma B"     NULL      "bar"
2   "Abteilung X" 0         "xxx"
3   "Werk 1"      1         "werk"
4   "Abteilung Y" 3         "yyy"
|
|
v
Code:
ID  Text                         Info
-------------------------------------------
0   "Firma A"                    "foo"
1   "Firma B"                    "bar"
2   "Firma A Abteilung X"        "xxx"
3   "Firma B Werk 1"             "werk"
4   "Firma B Werk 1 Abteilung Y" "yyy"

Wie kann ich dieses beim selecten mit SQL am besten erreichen?

Besten Dank im Voraus,
Medium

jfheins 3. Nov 2010 16:05

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
Zitat:

Zitat von Medium (Beitrag 1059361)
Die Ergebnismenge besteht dabei jedoch nicht nur aus einem einzelnen Datensatz, sondern derer Kaskaden können in der Basistabelle mehrfach sein, und auch unterschiedlich tief.
Es gibt mehr Felder als nur diese drei, und die anderen Felder sollen die Werte des gerade aufgelösten Datensatzes beibehalten. Es soll zudem jeder Datensatz aufgelöst werden.

Kannst du eine maximale Tiefe angeben? Imho ist es sonst nicht ohne weiteres in SQL formulieren. Wenn ja, kannst du die Tabelle n mal mit sich selbst joinen und dadurch bis zu n Felder verketten.

p80286 3. Nov 2010 17:14

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
in Oracle hilft Dir CONNECT BY weiter, aber ich weiß nicht ob MySQL das auch kann.
Gruß
K-H

Medium 3. Nov 2010 18:37

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
CONNECT BY habe ich in der MySQL Referenz leider nicht gefunden (wäre ja perfekt), aber ich glaube die Tiefe eingrenzen zu können. Den JOIN hatte ich auch im Sinn, war nur aus mir gerade nicht weiter bekannten Gründen der Auffassung, dass man eine Tabelle nicht mit sich selbst joinen konnte :stupid:. Ich probier das mal. Merci!

mkinzler 3. Nov 2010 18:39

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
Warum sollte man eine Tabelle nicht mit sich selber Joinen können?

Bummi 3. Nov 2010 18:42

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
Gibt es im MySQL temporäre Tabellen und Proceduren die diese als Result, sowie einfache Schleifenkonstrukte ("While") zurückliefern können?
Unter MS-SQLServer habe ich ähnliches auf die Art lösen können.

mkinzler 3. Nov 2010 18:44

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
Oder einer rekursiven SP

Medium 3. Nov 2010 18:51

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
Der JOIN klappt, allerdings werden leider auch nur die Sätze zurückgeliefert, die die entsprechende Tiefe aufweisen :(
Sind rekursive SPs in MySQL überhaupt wieder möglich? Mein letzter Stad war, dass dies aus technischen Gründen mal entfernt wurde. Edit: Okay, gibt's, ist aber off-by-default. Bummi, was du genau sagen willst, versteh ich gerade nicht so recht :oops:

mkinzler 3. Nov 2010 18:53

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
In MySQL kenne ich mich nicht so aus ( lange her) bei FB geht das, der kennt baer auch rekursive CTE

Bummi 3. Nov 2010 19:11

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
etwas in der Art
SQL-Code:
Select Cast(ID as Int) as ID, Parent, Cast([text] as Varchar(4000)) as text
into #tmp
from tree --where Parent is NULL


While Exists(Select * from #tmp join tree on tree.Parent=#tmp.ID)
Update #tmp set text = #tmp.text +' '+ tree.Text ,#tmp.ID=tree.id
from tree
where tree.Parent=#tmp.ID


Select * from #tmp
Drop table #tmp

Medium 3. Nov 2010 21:02

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
Hmhmhm, ich habe jetzt zunächst mit einer SP rumgespielt, wobei ich hier bisher nur mit einfachen Einzeilern rumgemacht habe. MySQL meckert einen Fehler in der letzten Zeile des folgenden an:
SQL-Code:
CREATE FUNCTION makefullname (name VARCHAR(255), pid INT)
RETURNS VARCHAR(255)
BEGIN
  DECLARE name2 VARCHAR(255);
  DECLARE pid2 INT;
  DECLARE c CURSOR FOR SELECT name, parentID FROM testtabelle WHERE id=pid;

  OPEN c;
  FETCH c INTO name2, pid2;

  IF pid2!=0 THEN
    RETURN CONCAT(name, ' ', makefullname(name2, pid2));
  ELSE
    RETURN name;

  CLOSE c;
END;
"END;" ist fast sicher richtig :). Aber wo ist mein Patzer wirklich? Zudem scheint mein MySQL server die Variable zum Verstellen der Rekursionstiefe nicht. Lustigerweise benennt das selbe Manual für die selbe MySQL Version (5.1) sowohl die Option zum Einstellen der maximalen Tiefe, schreibt in der Sektion zu Einschränkungen von SPs aber gleichzeitig "- Stored functions cannot be used recursively. Watten nu!? *seufz*

Das mit dem JOIN wäre so sexy gewesen. Im Zweifel werd ich morgen auch noch mal temporäre Tabellen versuchen - ich hoffe, dass das nicht zu langsam wird :\

mkinzler 3. Nov 2010 21:04

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
Was für einen Fehler?

Medium 3. Nov 2010 21:17

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
Zitat:

Fehler, währen die Abfrage ausgeführt wurde.

MySQL Fehlernummer1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 17
Der Fehler 1064 scheint laut Onkel Google öfter mal vorzukommen, und zwar bei einer ganzen Fülle von Operationen, worunter auch CREATE TABLEs und völlig andere Dinge gehören. Eine genauere Beschreibung zu dieser Nummer habe ich leider nicht finden können, wodurch die Meldung für mich so aussagekräftig wird wie "geht nicht" :\
Ich benutze übrigens den MySQL Administrator aus den GUI-Tools von MySQL.

omata 3. Nov 2010 22:24

AW: [SQL] Kaskadierende Eltern-Kind Beziehung in selber Tabelle auflösen
 
Es geht auch ohne Rekursion... klick


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz