MySQL Suche über mehrere Tabellen
Hiho Hiho,
wer die Überschrift liest, wird erstmal merken "da gibts eine Menge Stoff zu". Stimmt, aber irgendwie haut bei mir was nicht hin
Zum Problem: Ich habe eine MySQL Datenbank mit 4 Tabellen. Diese sind (fast) gleich aufgebaut,
ID | Titel | weitere Felder mit Informationen...
die Abweichung besteht eigentlich nur in der Anzahl der Felder.
Nun will ich eine einfache Suche ausführen lassen. User kommt also auf die Webseite und gibt Suchbegriff X ein, dieser soll dann brav aufgelistet werden. Im konkreten Beispiel wäre das eine Suche nach einem Filmtitel, der in einer oder mehreren Tabellen vorkommt. Mein Statement funktioniert aber nicht und ich sehe den Fehler nicht. Habe es auch schon oft geändert, aber nie das gewünschte Ergebnis erzielt. Der momentane Stand ist folgender:
Titel A steht in allen Tabellen und wird auch in allen gefunden.
Titel B steht nur in Tabelle 2, wird aber nicht gefunden. Komischerweise steht ja in Tabelle 2 auch Titel A, dieser wird gefunden.
Titel C steht in Tabelle 3, wird auch nicht gefunden. Titel A wird hier gefunden.
Titel D steht in Tabelle 4 und wird auch gefunden, aber nicht, wenn ich diesen auch in Tabelle 1 eintrage.
Mir gehen hier echt die Ideen aus. Ich bin für jede Antwort dankbar, die mich irgendwie weiterbringen könnte.
SELECT
tbl1.id AS table_one_id, tbl1.titel AS table_one_titel, tbl2.id AS table_two_id, tbl2.titel AS table_two_titel, tbl3.id AS table_three_id, tbl3.titel AS table_three_titel, tbl4.id AS table_four_id, tbl4.titel AS table_four_titel FROM
tabelle1 tbl1 RIGHT JOIN tabelle2 tbl2 ON tbl1.titel = tbl2.titel RIGHT JOIN tabelle3 tbl3 ON tbl1.titel ORt bl2.titel = tbl3.titel RIGHT JOIN tabelle4 tbl4 ON tbl1.titel OR tbl2.titel OR tbl3.titel = tbl4.titel WHERE tbl1.titel OR tbl2.titel OR tbl3.titel OR tbl4.titel = 'Titel B'
Mfg
Mitchell
wer die Überschrift liest, wird erstmal merken "da gibts eine Menge Stoff zu". Stimmt, aber irgendwie haut bei mir was nicht hin
Zum Problem: Ich habe eine MySQL Datenbank mit 4 Tabellen. Diese sind (fast) gleich aufgebaut,
ID | Titel | weitere Felder mit Informationen...
die Abweichung besteht eigentlich nur in der Anzahl der Felder.
Nun will ich eine einfache Suche ausführen lassen. User kommt also auf die Webseite und gibt Suchbegriff X ein, dieser soll dann brav aufgelistet werden. Im konkreten Beispiel wäre das eine Suche nach einem Filmtitel, der in einer oder mehreren Tabellen vorkommt. Mein Statement funktioniert aber nicht und ich sehe den Fehler nicht. Habe es auch schon oft geändert, aber nie das gewünschte Ergebnis erzielt. Der momentane Stand ist folgender:
Titel A steht in allen Tabellen und wird auch in allen gefunden.
Titel B steht nur in Tabelle 2, wird aber nicht gefunden. Komischerweise steht ja in Tabelle 2 auch Titel A, dieser wird gefunden.
Titel C steht in Tabelle 3, wird auch nicht gefunden. Titel A wird hier gefunden.
Titel D steht in Tabelle 4 und wird auch gefunden, aber nicht, wenn ich diesen auch in Tabelle 1 eintrage.
Mir gehen hier echt die Ideen aus. Ich bin für jede Antwort dankbar, die mich irgendwie weiterbringen könnte.
SELECT
tbl1.id AS table_one_id, tbl1.titel AS table_one_titel, tbl2.id AS table_two_id, tbl2.titel AS table_two_titel, tbl3.id AS table_three_id, tbl3.titel AS table_three_titel, tbl4.id AS table_four_id, tbl4.titel AS table_four_titel FROM
tabelle1 tbl1 RIGHT JOIN tabelle2 tbl2 ON tbl1.titel = tbl2.titel RIGHT JOIN tabelle3 tbl3 ON tbl1.titel ORt bl2.titel = tbl3.titel RIGHT JOIN tabelle4 tbl4 ON tbl1.titel OR tbl2.titel OR tbl3.titel = tbl4.titel WHERE tbl1.titel OR tbl2.titel OR tbl3.titel OR tbl4.titel = 'Titel B'
Mfg
Mitchell
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 180542
Url: https://administrator.de/contentid/180542
Ausgedruckt am: 19.12.2024 um 13:12 Uhr
19 Kommentare
Neuester Kommentar
Über die Datenmodellierung der Datenbank will ich jetzt erstmal kein Wort verlieren, die verkompliziert das ganze aber deutlich.
Also so wie ich das sehe, ist Join auch die völlig falsche Vorgehensweise.
Wenn ich das richtig verstehe, sind die 4 Tabellen praktisch unabhängig voneinander. Wozu dann ein Join der Tabellen untereinander?
Wenn ich unabhängige Tabellen habe und die in einer Ausgabe zusammenführen will, ist eine SQL Union das richtige.
Also etwas in der Art (falls MySQL union kennt):
select ID, Titel from table_one_titel where Titel='Titel B'
union
select ID, Titel from table_two_titel where Titel='Titel B'
union
select ID, Titel from table_three_titel where Titel='Titel B'
union
select ID, Titel from table_four_titel where Titel='Titel B'
Also so wie ich das sehe, ist Join auch die völlig falsche Vorgehensweise.
Wenn ich das richtig verstehe, sind die 4 Tabellen praktisch unabhängig voneinander. Wozu dann ein Join der Tabellen untereinander?
Wenn ich unabhängige Tabellen habe und die in einer Ausgabe zusammenführen will, ist eine SQL Union das richtige.
Also etwas in der Art (falls MySQL union kennt):
select ID, Titel from table_one_titel where Titel='Titel B'
union
select ID, Titel from table_two_titel where Titel='Titel B'
union
select ID, Titel from table_three_titel where Titel='Titel B'
union
select ID, Titel from table_four_titel where Titel='Titel B'
Hallo Mitchell,
also UNION hört sich eigentlich ganz gut an. Und wenn UNION ALL die doppelten Datensätze rausfiltert, dann hat es irgendwie seine Funktion verfehlt. Aber um zu wissen, aus welcher Tabelle der Eintrag stammt, könntest Du auch noch eine Konstante 'Tabelle x' AS Tabelle in jede der vier Teilabfragen einbauen, dann kannst Du schwer überhaupt noch Dubletten haben.
Falls Du aber unbedingt mit joins zum Ziel kommen willst, dann solltest Du kein RIGHT JOIN, sondern eher ein FULL JOIN verwenden.
Gruß, Mad Max
also UNION hört sich eigentlich ganz gut an. Und wenn UNION ALL die doppelten Datensätze rausfiltert, dann hat es irgendwie seine Funktion verfehlt. Aber um zu wissen, aus welcher Tabelle der Eintrag stammt, könntest Du auch noch eine Konstante 'Tabelle x' AS Tabelle in jede der vier Teilabfragen einbauen, dann kannst Du schwer überhaupt noch Dubletten haben.
Falls Du aber unbedingt mit joins zum Ziel kommen willst, dann solltest Du kein RIGHT JOIN, sondern eher ein FULL JOIN verwenden.
Gruß, Mad Max
weil ich die Tabellen ja miteinander verknüpfen muss, damit auch in jeder gesucht wird. Wirst du in jedem Handbuch/Tutorial so finden.
Nein, wird man so nicht finden. Fremdschlüsselbeziehungen setzen voraus, daß die Inhalte der Felder auch eine Beziehung haben.
Bei Dir sind zufällig in den 4 Tabellen in jeweils einer Spalte ein Wert drin den Du suchen möchtest. Das ist keine Schlüsselbeziehung.
Wenn Du die Info brauchst, in welcher Tabelle der Wert gefunden wird, dann Union mit Angabe der Tabelle wie von Mad Max vorgeschlagen.
Oder, anderer Vorschlag:
Mach eine View über alle Titelspalten der 4 Tabellen (mit Union)
Damit ist sichergestelt, daß alle Titel drin sind.
Und dann einen Join aller Tabellen gegen diese View. Da alle Werte in der View drin sind, kann man auch zu jeder Zeile dort einen Join gegen die Werte der anderen Tabellen ausführen.
mit 4 Tabellen. Diese sind (fast) gleich aufgebaut,
da ist es wohl durchaus sinnvoll für jede Tabelle eine spezialisierte SQL Anweisung für die Suche zu schreiben - und die Ergebnisse dann zurück zu geben.Statement:
mich wundert, dass dein Statement überhaupt ohne Fehlermeldung ausgeführt wird, da die Feldnamen nicht überein stimmen.SELECT `id`, `titel`, 'table_1' AS 'table' FROM `table_1` WHERE `titel` = 'Titel A'
UNION
SELECT `id`, `titel`, 'table_2' AS 'table' FROM `table_2` WHERE `titel` = 'Titel A'
UNION
SELECT `id`, `titel`, 'table_3' AS 'table' FROM `table_3` WHERE `titel` = 'Titel A'
UNION
SELECT `id`, `titel`, 'table_4' AS 'table' FROM `table_4` WHERE `titel` = 'Titel A'
Ich frage mich aber: Warum sind die Daten in verschiedenen Tabellen ? Wäre es evtl sinnvoll ein View mit allen Daten zu erstellen - oder gar eine separate Tabelle ?
die Beziehung wird doch durch den Schlüssel ID hergestellt
Das würde aber bedeuten, daß in Tabelle 1 die Zeile ID 1 und in Tabelle 2/3/4 die Zeile mit ID 1 eine Beziehung miteinander haben. Der Aussage, daß die Titel in allen vorkommen können, aber nicht müssen, sagt doch eigentlich, daß dem nicht so ist.Nur weil Spalten gleich heißen, hat das noch nichts mit Beziehungen zu tun.
Um auf den Kommentar von nxclass zurückzukommen, eine Tabelle mit allen Titeln wäre vermutlich eine sinnvollere Datenmodellierung, die unterschiedliche Anzahl an Datenspalten kann man dann ja über separate Tabellen abwickeln, die man über Beziehungen und Join miteinander verbindet.
Aber schau Dir mal das Union Statement von nxclass an, daß wird Dir vermutlich weiterhelfen.
Er zeigt mir alles als tbl1 an
Was soll er denn bei deinem Union sonst machen? Union packt alle Ergebnisse in EIN Recordset. Und Spalten haben genau EINEN Titel. Wo soll da die Info herkommen, in welcher Tabelle es steht?stünde ich dann nicht vor dem selben Problem, wie jetzt? Mit dem Unterschied, dass ich nicht über 4 Tabellen muss, sondern über 10.
Nein, weil der Suchbegriff in einer vorkommt (damit nur eine where Bedingung) und wir Beziehungen zu den anderen Tabellen haben, die für einen Join geeignet sind.verwirrt mich ein wenig. Du willst, dass ich dem Feld "table_1 ein Alias gebe? Das Feld existiert nicht. Meinst du vielleicht ein Alias für die Tabelle "...FROM 'table_1' table?
Kein Feld, es ist eine Textkonstante.Du hast Dich ja beschwert, daß in Deinem Union Du nicht mehr erkennen kannst, aus welcher Tabelle der Treffer kommt.
Deswegen schlägt nxclass vor, daß du je nach Tabelle eine Textkonstante table_1, table_2 etc. der Daten-Zeile hinzufügst, damit Du hinterher erkennen kannst, aus welcher Tabelle der Treffer kommt.
Und wenn man mit SQL auf Kriegsfuss steht, gibt es immer noch die Möglichkeit in PHP oder womit die Webseite auch immer zusammengebastelt ist 4 Selects abzusetzen und es im Programm zusammenzusetzen.
... weil mir ein Freund dazu geraten hat wegen der Übersichtlichkeit. Ich hatte die Daten vorher in einer Tabelle.
... was haltet ihr denn für besser?
weder dein Freund noch Du brachst "Übersicht" über deine Daten - dafür ist die Datenbank da.... was haltet ihr denn für besser?
Alles in eine Tabelle zu packen ist möglich aber für MySql nicht sinnvoll.
Überlege doch mal was zusammen gehören könnte: Beispiel
- ein Film hat einen Titel, Genre, ...
- ein Film hat mehrere Eigenschaften wie Länge, Beschreibung, etc
Tabelle: 'filme' - Felder: 'id_film, titel, genre, ...'
Tabelle: 'eigenschaften' - Felder: 'id_eigenschaft, eigenschaft'
Tabelle: 'filmeigenschaften' - Felder: 'id_film, id_eigenschaft, eigenschaft_wert'
die Datenbank müsste dann doch nicht in mehreren Tabellen suchen, sich mit JOINs rumschlagen
MySql ist aber genau dafür optimiert - und mit meinem Beispiel kannst Du die Suche mit einer Anweisung ausführen.müsste dann doch nicht in mehreren Tabellen suchen
die eigentliche Suche sollte im besten Fall auch gar nicht in der Tabelle stattfinden - dafür erzeugt man einen Index in der Tabelle filme über die Spalten id_film und titelEs gibt dann noch andere Tricks um die Suche zu beschleunigen.
nahekommen sollte, zumindest habe ich es so verstanden
moment - Bei einer Suche:SELECT * FROM tbl1 WHERE titel LIKE '%{suchstring}%';
SELECT tbl2.eigenschaft_wert, tbl3.eigenschaft
FROM tbl2 JOIN tbl3 ON tbl2.id_eigenschaft = tbl3.id
WHERE tbl2.id_film = {FILM_ID}
tbl1: Filme
tbl2: Film_Eigenschaften
tbl3: Eigenschaften
Dieser Vorschlag ist insofern Vorteilhaft, wenn nicht jeder Film die selbe Anzahl Eigenschaften besitzt.
Zu den Eigenschaften kann man natürlich noch den Titel und den Genre dazu nehmen - dann kann man mit einem Suchbegriff über das Feld 'eigenschaft_wert' eigentlich alles Finden.
1.
Eine Suche wird mit der Zeit sehr langsam werden. Lässt sich umständlich erweitern - also nur durch ändern der Tabellen Struktur. Sehe da keine Vorteile2.
Eine Datenabfrage wird dadurch sehr umständlich. Sowas kann man zB. mit Beschreibungs Texten machen, diese könnte man ich eine extra Tabelle packen.