Hallo,
sofern du die maximale Anzahl an Schritten, durch die du suchen möchtest, konstant halten kannst (z.B. 6) wäre ein statisches SQL mit Unions und Self-Joins eine mögliche Lösung.
Ich gebe jetzt mal folgende fiktive Tabellenstruktur vor für die Punktepaare: (für deine Tabelle von Punkten/Verbindungen):
SQL:
Create table connections (
start integer(4),
target integer(4)
);
Das einfachste was eintreten kann, wäre ja dass zwei Elemente/Punkte direkt miteinander verbunden sind. In dem Fall reicht eine ganz normale Abfrage ohne Joins.
SQL:
select conn.start,
conn.target,
from connections conn
where conn.start = $startwert
and conn.target = $endwert
Für den Fall, dass zwei Elemente über einen Punkt miteinander verbunden sind (egal welcher), würdest du eine Abfrage mit einem Self-Join nutzen. Hierbei würde in "conn2.start" der Zwischenpunkt stehen.
SQL:
select conn1.start,
conn2.start,
conn2.target
from connections conn1,
connections conn2
where conn1.target = conn2.start
and conn1.start = $startwert
and conn2.target = $endwert
Und für den Fall, dass genau zwei Stationen zwischen dem Start- und Endpunkt liegen kann die Query folgendermassen aussehen.
In dieser Query stehen in conn2.start und conn3.start die jeweiligen Zwischenpunkte.
SQL:
select conn1.start,
conn2.start,
conn3.start,
conn3.target
from connections conn1,
connections conn2,
connections conn3
where conn1.target = conn2.start
and conn2.target = conn3.start
and conn1.start = $startwert
and conn3.target = $endwert
und so weiter für mehr Zwischenschritte/-punkte.
Um das ganze jetzt ein wenig aufzubereiten und mehrere mögliche Fälle gleichzeitig zu untersuchen, also alle Wege anzuzeigen, die ohne einen, mit genau einem oder mit genau zwei Zwischenschritten zum Ziel führen, kann man ein UNION ALL, eine Supportfunktion (concat_ws) und eine zusätzliche Spalte nutzen, z.B. so:
SQL:
select concat_ws(' => ', conn.start, conn.target) AS pfad,
0 AS anz_schritte
from connections conn
where conn.start = $startwert
and conn.target = $endwert
UNION ALL
select concat_ws(' => ', conn1.start, conn2.start, conn2.target),
1
from connections conn1,
connections conn2
where conn1.target = conn2.start
and conn1.start = $startwert
and conn2.target = $endwert
UNION ALL
select concat_ws(' => ', conn1.start, conn2.start, conn3.start, conn3.target),
2
from connections conn1,
connections conn2,
connections conn3
where conn1.target = conn2.start
and conn2.target = conn3.start
and conn1.start = $startwert
and conn3.target = $endwert
Die weiteren Joins zu den Daten der einzelnen Punkte hab ich jetzt mal aussen vorgelassen.
Eine Alternative wäre vielleicht noch eine Stored Procedure / Function.
Markus