Autor Beitrag
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 26.11.08 19:05 
Moin!

Ich brauch mal wieder (My-)SQL-Nachhilfe... ;)

Ich habe eine Tabelle, die vereinfacht so aufgebaut ist:
  • id(int)
  • titel(varchar)
  • parent(int)
Dabei enthält parent wiederum ein id einer anderen Zeile, kann also als Zeiger auf den Vorgänger aufgefasst werden. Die ID:1 ist die Wurzel des Baums, immer da und kann nicht geändert werden.

Jetzt kommt´s 8) Die Struktur der Zeilen ist wie ein Ordnerbaum im Dateisystem zu verstehen, es ist also ein Baum. Ich muss nun prüfen, ob es zirkuläre bzw. ungültige Referenzen und/oder verwaiste Objekte gibt. :?

OK, ich könnte jetzt hingehen und die Struktur per einzelner Selects lesen und in PHP/Delphi abbilden, dann die üblichen verdächtigen Algorithmen aus der Graphentheorie anwenden - aber geht das nicht auch "elegant(er)" mit SQL? :nixweiss:

cu
Narses

//EDIT: Tabellenstruktur angepasst

_________________
There are 10 types of people - those who understand binary and those who don´t.


Zuletzt bearbeitet von Narses am Mi 26.11.08 19:35, insgesamt 1-mal bearbeitet
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Mi 26.11.08 19:26 
Weiß nicht, ob das in MySQL auch so ist, da ich selber nur mit Interbase arbeite
Du könntest Next als Foreign Key auf Tabelle.ID deklarieren. Somit MUSS die ID existieren, die du in Next angibst.

ausblenden SQL-Anweisung
1:
ALTER TABLE TABLE1 ADD CONSTRAINT TABLE1_FK FOREIGN KEY (nextREFERENCES TABLE1(ID) ON UPDATE CASCADE ON DELETE CASCADE;					

Das "On update" bzw. "on delete" gibt an, was passieren soll, wenn eine ID geändert / gelöscht wird.
Mit Cascade, werden alle Next's, die darauf zeigen, mit angepasst (Achtung: Beim Delete werden diese mit gelöscht!)

Edit: Da fällt mir auf, zirkuläre Verweise findest du damit nicht.. du stellst höchstens sicher, dass die ID, auf die Next zeigt, existiert (sonst gibts nen Fehler beim Anlegen).

_________________
PROGRAMMER: A device for converting coffee into software.
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 26.11.08 19:37 
Moin!

Du hast mir doch letztes Mal schon geholfen :gruebel: danke für deinen Einsatz! :zustimm:

Nettes Feature, allerdings - wie du schon gesagt hast - damit findet man keine Kreise im Graphen. :(

Ich habe grade gemerkt, dass ich die Tabellen-Struktur nicht korrekt abgebildet habe, es ist keine Nachfolger-, sondern eine Vorgänger-Kette. :idea: Noch ´ne andere Idee? :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mi 26.11.08 19:56 
Wenn sicher gestellt ist, dass die ID für jeden neuen Datensatz immer größer wird (Auto-Increment), sollte Dir eine solche Abfrage ungültige Einträge liefern:
ausblenden SQL-Anweisung
1:
select id from yourtable where parent > id					

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mi 26.11.08 20:47 
Du könntest zuerst mal die Referenzielle Integrität der Tabelle prüfen, d.h. dass es keine Ungültigen Verknüpfungen gibt:

Datensätze mit ungültigen Parents (non-existent parent):
ausblenden SQL-Anweisung
1:
SELECT id FROM tbl WHERE NOT (parentid in (SELECT DISTINCT id from tbl)) AND id <> 1					


Danach die Anwendung der entsprechenden graphentheoretischen Algorithmen für die Kreis-Erkennung in ne Stored Procedure packen und diese Selecten.

Den Hinweis von Christian kann man hier als goldwerten Tipp nehmen, wenn diese Eigenschaft der Daten bereits gegeben ist. Ansonsten sollte man diese durch einen View entsprechend erzeugen.

Ferner bieten manche DBMS (bekannt von Oracle) sog. Hierarchische Selects an. Diese kann man u.U. dazu missbrauchen, um jegliche Datensätze zu filtern, denen das DBMS keine eindeutige Ebene zuordnen kann. Ist diese Option nicht möglich, kann man dies mit einer\zwei Temporär-Tabellen nachbilden, von denen die erste alle Quell-IDs enthält und die zweite Schritt für Schritt mit all den IDs befüllt wird, die mit den derzeitig in der Tabelle enthaltenen IDs über den Parent erreicht werden können:
ausblenden SQL-Anweisung
1:
INSERT INTO tmptbl_reachable SELECT id FROM tmptbl_allids WHERE tmptbl_allids.id IN (SELECT id FROM tmptbl_reachable)					

Solange neue Datensätze hinzugefügt wurden, fortsetzen. Solange Datensatz 1 nicht auf einen weiter unten in der Hierarchie versteckten Datensatz zeigt, ist bei diesem Ansatz die Kreisfreiheit garantiert ;-) (Beweis bleibt dem Fragesteller überlassen).

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 28.11.08 00:52 
Moin!

OK, ich merke schon, meine bescheidenen Kenntnisse von SQL sind hier definitiv zu wenig... :(

Also habe ich die Elemente in ein Array gelesen und arbeite im RAM damit, statt das DBMS zu belästigen, geht auch... :? :nixweiss:

Trotzdem danke für die Vorschläge. :)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 28.11.08 01:58 
Müsste auch so gehen (2 Aliase auf dieselbe Tabelle):
ausblenden SQL-Anweisung
1:
2:
3:
SELECT A.Id FROM Tabelle A
LEFT JOIN Tabelle B ON B.Id = A.Parent
WHERE B.Id IS NULL