DB-Frage
Hirsch
- php
Hallo,
Ich habe eine DB etwa so
ID PID
1 0
2 1 g1
3 1 g2
4 1 g3
5 1 g4
6 1 g5
7 2 a1
8 2 a2
9 3 b1
10 9 bb1
11 10 bbb1
Wie bekomme ich den wert "g2" raus wenn ID=11 (bzw PID=10 od. bzw bbb1)?
Ich möchte am besten aus der ID oder PID heraus den "Vater" finden können aber immer WHERE PID='1'
also ID:7 = ID:2 bzw. g1
also ID:8 = ID:2 bzw. g1
oder ID:9 = ID:3 bzw. g2
oder ID:10 = ID:3 bzw. g2
oder ID:11 = ID:3 bzw. g2
Klar?
Wäre cool wenn mir da jemanden bei der SQL-Abfrage oder for-schleifen gestaltung helfen könnte.
Vielen Dank im Voraus!!!
Hirsch
Hi Hirsch,
Klar?
Nein, vielleicht solltest du erst mal sagen, was du überhaupt machen willst.
Du hast drei Spalten:
ID | PID | [hier hast du keinen Namen angegeben]
-----+-----+--------------------------------------
1 | 1 | [ein beliebiger String]
Habe ich das soweit richtig interpretiert?
Mal ins Blaue geraten: Soll das vielleicht ein Forum geben?
Oder zumindest andere Daten, die in einer BaumStuktur abgelegt werden sollen?
Die Vater ID kannst du aber nicht einfach herrausfinden - woher willst du
wissen, wo in die Struktur der Datensatz hingehört? Deshalb speichert man
zumindest bei einem Forum auf DB Basis immer noch die Vater ID mit ab.
Vielleicht hilft dir auch dieser Feature Artikel weiter...
MfG, Dennis.
Hi,
Du hast drei Spalten:
ID | PID | [hier hast du keinen Namen angegeben]
-----+-----+--------------------------------------
1 | 1 | [ein beliebiger String]Habe ich das soweit richtig interpretiert?
Ja
Mal ins Blaue geraten: Soll das vielleicht ein Forum geben?
Oder zumindest andere Daten, die in einer BaumStuktur abgelegt werden sollen?
Kein Forum aber Baumstruktur!
Die Vater ID kannst du aber nicht einfach herrausfinden - woher willst du
wissen, wo in die Struktur der Datensatz hingehört? Deshalb speichert man
zumindest bei einem Forum auf DB Basis immer noch die Vater ID mit ab.
Na klar kann man diese herausfinden, wenn ich einen Baum nach unten hin aufbauen kann muss ich ihn doch auch nach oben hin lesen können bis zur pid 1.
Der Link war damals hilfreich beim aufbauen dieser struktur, aber jetzt gehts ja in die andere richtung =)
Hoirsch
Hi Hirsch,
Oder zumindest andere Daten, die in einer BaumStuktur abgelegt werden sollen?
Kein Forum aber Baumstruktur!
Gut, dann benötigst du aber 3 Informationen. Bis jetzt hast du eine einmalige ID, diese bezeichnet nur den Datensatz selber, sonst kann man damit nichts anfangen. Dann hast du die „Grupppen ID” (bei einem Forum würde man von Thread ID sprechen) - hieraus kannst du ablesen welcher Gruppe der Datensatz angehört, aber Informationen wo der Datensatz in der Gruppe vorkommt findest du auch hierin nicht. Dazu brauchst du dann schon die „Vater ID”, also die ID des Datensatzes, dem dieser Datensatz untergeordnet ist.
Ein kleines Beispiel:
ID | PID | Titel
-----+-----+-------
1 | 1 | a
2 | 1 | b
3 | 1 | c
4 | 2 | foo
5 | 2 | bar
6 | 1 | x
7 | 2 | y
Fagen wir mal mit den ersten 3 Sätzen an: Alle gehören Gruppe 1 an - doch welches ist das „Ausgangsposting”? Ok, sagen wir mal das mit der ID 1, weil es das erste ist und dann sagen wir noch, dass das nächte (ID 2) eine Antwort auf ID 1 sein muss, weil nichts anderes an dieser Stelle möglich ist.
Doch jetzt kommt ID 3 - ist es eine Antwort auf ID 1? Oder ist es eine Antwort auf ID 2? Und gar erst ID 6: Ist es eine Antwort auf ID 2? Oder ID 3? Oder doch ID 1?
Alleine die erste Gruppe (entspricht Thread) könnte schon so aussehen:
Oder:
Oder:
Du siehst es gibt also wenn man von einer Anzahl „Postings” ausgeht die unendlich ist auch unendlich viele Möglichkeiten wie der „Thread” aufgebaut/strukturiert ist.
Na klar kann man diese herausfinden, wenn ich einen Baum nach unten hin aufbauen kann muss ich ihn doch auch nach oben hin lesen können bis zur pid 1.
Nein, die Vater ID ist nichts was du berrechnest - es ist eine (wichtige) Information wo in der Struktur ein Posting sich befindet. Wenn du die berrechnen könntest, könntest du auch berrechnen wo ich mich morgen um 16:30 Uhr aufhalten ;-)
Der Link war damals hilfreich beim aufbauen dieser struktur, aber jetzt gehts ja in die andere richtung =)
Wenn du eine Struktur hast, kannst du diese natürlich in beide Richtungen durchgehen bzw. abarbeiten klar, aber dein Problem ist, dass du diese Struktur gar nicht hast, weil du keine Vater ID hast.
MfG, Dennis.
Sorry Dennis,
Du hast den OP nicht verstanden. Du hast auch nicht verstanden, wie der OP den "Vater", ich würde es eher Wurzel nennen, definiert. Deswegen verfehlst Du mit Deinen Folgerungen leider das Thema.
Nein, die Vater ID ist nichts was du berrechnest - es ist eine (wichtige) Information wo in der Struktur ein Posting sich befindet. Wenn du die berrechnen könntest, könntest du auch berrechnen wo ich mich morgen um 16:30 Uhr aufhalten ;-)
Die ID der Wurzel ist, wenn der Baum sauber aufgebaut ist, d.h. keine Zirkularbezüge enthält, sehr wohl berechenbar.
Wenn du eine Struktur hast, kannst du diese natürlich in beide Richtungen durchgehen bzw. abarbeiten klar, aber dein Problem ist, dass du diese Struktur gar nicht hast, weil du keine Vater ID hast.
Selbstverständlich hat der OP eine Wurzel definiert. Dies ist der Eintrag mit der Parent-ID 1. Diese Definition halte ich für nicht ganz glücklich, meiner Meinung nach wäre es besser, wenn ein Wurzeleintrag als Parent-ID die NULL gewählt würde. Somit kann sich der OP den künstlichen ersten Tabelleneintrag sparen, den er sowieso nicht nutzt.
Weiterhin muss beim Aufbau des Baumes durch die Anwendung darauf geachtet werden, dass jeder Knoten, jedes Blatt eine eindeutige Wurzel aufweist. Mehrere Wurzeln wären prinzipiell gesehen auch möglich. Wenn Du den Baum nun von der Wurzel aus aufbaust, wirst Du feststellen, dass jeder Knoten in einer bestimmten Tiefe liegt. Obwohl es eine redundante Information ist, kann es aus Performancegründen interessant sein, die Tiefe in einer eigenen Spalte mit abzuspeichern (indiziert selbstverständlich). Denn der Elternknoten liegt exakt in einer um 1 kleineren Tiefe.
Bei besseren DBMS (als das heutige MySQL 4.x), d.h. bei einem, das "stored procedures" unterstützt, kann man recht einfach eine SP schreiben, die als Rückgabewert die ID, d.h. den Wert des Primärschlüssels des Wurzelknotens zurückliefert. Somit kann auch jedes davon eindeutig abhängige Feld dieser Tabelle eindeutig bestimmt werden.
Stehen SP nicht zur Verfügung, so ist diese Funktionalität am einfachsten in der API, d.h. in der Anwendung selbst zu lösen.
Freundliche Grüße
Vinzenz,
der hofft, den OP richtig verstanden zu haben.
Ich gehe davon aus, dass bei id=8 als Ergebnis g1 erwartet wird.
Die ID der Wurzel ist, wenn der Baum sauber aufgebaut ist, d.h. keine Zirkularbezüge enthält, sehr wohl berechenbar.
Jep!
Selbstverständlich hat der OP eine Wurzel definiert. Dies ist der Eintrag mit der Parent-ID 1. Diese Definition halte ich für nicht ganz glücklich, meiner Meinung nach wäre es besser, wenn ein Wurzeleintrag als Parent-ID die NULL gewählt würde. Somit kann sich der OP den künstlichen ersten Tabelleneintrag sparen, den er sowieso nicht nutzt.
Das hat seine Gründe!!
der hofft, den OP richtig verstanden zu haben.
Ich gehe davon aus, dass bei id=8 als Ergebnis g1 erwartet wird.
JA JA JA!!
Genau das ist gemeint!
Du hast es völlig durchblickt!
Ich brauch aber auf jeden fall ne for schleife gelle?
Das geht mir zu hoch...
Hirsch
Hallo HIrsch
Ich brauch aber auf jeden fall ne for schleife gelle?
Ja. Falls Dein DBMS den entsprechenden Sprachumfang von SQL unterstützt, bevorzugt in SQL, falls nicht in der Anwendung.
Welches Datenbankmanagementsystem steht Dir in welcher Version zur Verfügung?
Das geht mir zu hoch...
So schwer sind Schleifen nun auch wieder nicht. Für Dein Problem der Algorithmus (ohne Fehlerbehandlung) in einer Art Pseudocode:
Ermittle zur gegebenen ID die Parent-ID
Solange die Parent-ID grösser ist als 1
ID := Parent-ID
Ermittle die Parent-ID zur ID
Ende Solange
Wenn Parent-ID gleich 1
Ermittle den Inhalt der Suchspalte zur ID
Sonst
Fehler aufgetreten
Ende Wenn
Wenn Dein Baum unsauber aufgebaut ist, dann kannst Du in die schönste Endlosschleife geraten. Deswegen mein Tipp: Speichere die (redundante, da berechenbare) Tiefe jedes Knotens mit ab. Zähle die Anzahl der Schleifendurchläufe mit. Ist sie größer als die maximale Tiefe, breche mit einer Fehlermeldung ab.
Sollte weder in SQL noch in der Anwendung schwer zu schreiben sein.
Freundliche Grüße
Vinzenz
Hi!
Vielen Dank bis hier hin schonmal!!
Welches Datenbankmanagementsystem steht Dir in welcher Version zur Verfügung?
Also ich habe Mysql ... ähm ... moment ... 3.23.58 (Client API version - ist es das aus php_info()? )
Kann ich da so einen SQL-Code einbauen, wenn ja wie würde der aussehen?
Danke nochmal!
Hirsch
echo $begrüßung;
Welches Datenbankmanagementsystem steht Dir in welcher Version zur Verfügung?
Also ich habe Mysql ... ähm ... moment ... 3.23.58 (Client API version - ist es das aus php_info()? )
Nein, die Client-API-Version ist nicht zwingend die gleiche Nummer wie die MySQL-Server-Version.
mysql_get_server_info() beispielsweise gibt Auskunft über die Server-Version.
echo "$verabschiedung $name";
HI!!
mysql_get_server_info() beispielsweise gibt Auskunft über die Server-Version.
3.23.58-log
*gg*
Hirsch
echo $begrüßung;
mysql_get_server_info() beispielsweise gibt Auskunft über die Server-Version.
3.23.58-log
In dem Fall ist es die gleiche Versionsnummer.
*gg*
Du brauchst da gar nicht so zu grinsen. Ich grinse dann nämlich zurück, wenn du mit einer 3er Client-API (damit wird PHP4 für Windows ausgeliefert) auf einen 4.1er Server zugreifen willst. :-)
echo "$verabschiedung $name";
Ich weiß immernoch nicht wie ich vorgehen soll =(
echo $begrüßung;
Ich weiß immernoch nicht wie ich vorgehen soll =(
MySQL 3.irgendwas kann noch nicht besonders viel. Worauf Vinzenz hinaus wollte wird sicher eine Stored Procedure sein. MySQL kann das erst ab 5.irgendwas.
Dir wird dann wohl nur die Methode von Vinzenz übrigbleiben.
Etwas aufwändiger zu pflegen, dafür aber mit mehr eleganteren Abfragemöglichkeiten ausgestattet wäre noch ein Nested Set.
echo "$verabschiedung $name";