MySQL Relationship mehrere Tabllen verbinden und in der SQL Query ohne Join selektieren?
Hallo
wenn man in MySQL mehrere Tabellen mit Relations verbindunden hat, kann man diese dann Selekteiren ohne Join? Beir mir hat dies nicht funktioniert.
Hier der SQL befehl
SELECT * FROM Users, Infos, Addresses WHERE Users.User_TOKEN = "XY"
Da ich aber in der Tabelle Adresses mehrere einträge habe würde mir jeder dieser einzelnen Einträge in Verbindung mit einem Eintrag aus Users und Infos gezeigt.
4 Antworten
Ein SELECT * FROM tabelle-1 bringt alle Sätze der Tabelle tabelle-1.
Ein SELECT * FROM tabelle-1, tabelle-2 bringt alle Sätze beider Tabellen jeweils nebeneinander in einer Zeile in Kombination miteinander. Dabei wird jeder Satz der tabelle-1 mit jedem Satz der tabelle-2 verknüpft. Bei zwei Tabellen mit jeweils 100 Sätzen ergäbe das 10 000 Zeilen. Um das zu verhindern, weil man vermutlich das gar nicht haben will, kann man mit WHERE Bedingungen festlegen, welche Sätze wie verknüpft werden sollen. Mit JOIN geht das im idealen Fall natürlich auch. Mit WHERE geht das aber immer, auch ohne Fremdschlüssel und dergleichen. Man kann die Verknüpfung so formulieren, wie man sie haben will und die Datenbank macht das, völlig transparent und überschaubar.
Ich betreibe eine Datenbank für einen Rassehundeverein mit 57 Datenbanktabellen. Da werden z.T. bis zu 5 Tabellen miteinander verknüpft. Bei Ahnentafeln werden die Welpen mit ihren Eltern und Großeltern verknüpft, die sich sogar in der selben Tabelle befinden. Auch das geht. Natürlich benutze ich auch Fremdschlüssel dort, wo ich sie gebauchen kann. Verknüpfungen habe ich aber weit mehr. Ich mache die grundsätzlich alle mit WHERE. Die Datenbank kann weit mehr als die normierten Schulbeispiele aus dem Informatikunterricht. Für die Schule ist das auch o.k., sie muss ja nur die Grundlagen und das Prinzip vermitteln.
Wenn Du also mehrere Tabellen zum Verknüpfen hast, musst Du zunächst alle diese Tabellen beim SELECT aufzählen, dann gibst mit einem WHERE alle Bedingungen zur Verknüpfung und nicht vergessen, auch die weiteren Bedingungen für die Selektion an.
Hier ein Beispiel:
In der Tabelle welpe stehen alle Hunde mit ihrer Zuchtbuch-Nr (zbnr), Namen (wname) und sonstigen persönlichen Daten (Farbe, Geschlecht) und einer Wurf-Nr (wunr), die auf den Wurft verweist.
In der Tabelle wurf stehen alle Würfe mit der Wurf-Nr (wunr), Wurftag (wtag), Zuchtbuch-Nrn der Eltern (zbvat, zbmut) und einer Zwinger-Nr (zwid) als Verweis auf den Zwinger.
In der Tabelle zwnam stehen alle Zwinger mit der Zwinger-Nr (zwid) und dem Zwingernamen (zname).
Nun möchte ich einen Welpen mit der zbnr = 123456 komplett mit Zuchtbuch-Nr, Welpennamen, Zwingernamen, Wurftag und Zuchtbuch-Nrn seiner Eltern anschauen:
SELECT zbnr, wname, zname, wtag, zbvat, zbmut
FROM welpe, wurf, zwnam
WHERE welpe.wunr = wurf.wunr
AND wurf.zwid = zwnam.zwid
and zbnr = 123456
Alternativ könnte ich auch mir alle Welpen anzeigen lassen, die als Vater die Zuchtbuch-Nr 123123 haben (statt letzte Zeile):
and zbvat = 123123
Dabei beachten: Wenn Deine Bedinungen auch OR in Kombination mit AND enthalten, musst Du ggf. Klammern verwenden, z.B:
and (zbvat = 123123 OR zbvat = 123444)
Hello there,
nein, so wie du das machst, würdest du ein kartesisches Produkt über drei Tabellen machen und hättest 8 mal so viele Ergebnisse wie du eigentlich willst, weil du alles mit allem kombinieren würdest.
Ein Join ist unabdingbar. Wenn du aber das Schlüsselwort JOIN nicht verwenden willst, kannst du implizite Joins nehmen, so wie du das hier gemacht hast.
Dann musst du aber weitere WHERE-Statements mit AND hinzufügen und jeweils den Fremdschlüssel BenutzerID aus den Tabellen Infos und Addresses gleichsetzen mit dem Primärschlüssel BenutzerID aus der Tabelle users.
Also vermutlich etwa so:
SELECT *
FROM Users, Infos, Addresses
WHERE infos.UserID = users.UserID
AND addresses.UserID = users.UserID
AND Users.User_TOKEN = "XY
Ganz besonders hässlich ist natürlich das SELECT * über drei Tabellen. Icbh kann mir nicht vorstellen, dass du das wirklich alles brauchst. Selektiere - außer zum puren Testen - immer nur die Spalten die du auch brauchst.
Hoffe ich konnte dir helfen.
MfG
Alex
Ah, voll der Müll ... :-)
Gewöhne Dir bitte an, alles kleinzuschreiben - also "user" statt "User" und nur abzufragen, was Du brauchst. Also nicht * sonder user_toker, user_ip, user...
Prinzipiell ist es ganz einfach - wenn man die Struktur kennt - mehrerer Felder auszulesen. Aber mit deinem Befehl haut das sicher nicht hin.
Du fagst ab:
"Zeige mir alles aus 3 Tabellen wo der token xy ist!"
Liest Dir das mal laut vor (min 3x) und überlege Dir, ob es das ist, was Du wolltest!
Du musst die Struktur kennen, um darauf zuzugreifen!?
select * from tab_1.user, tab_2.info where tab_1.user.id = "xy" AND tab_2.info.key = "abc";
aber der tab_2.info.key bekomme ich erst du die spalte in der Users tabelle die da hinterlegt ist
dann schreib es halt um ... :)
sorry - ich verstehe leider nicht, was du möchtest und weiß nicht, wie die datenbank aufgebaut ist.
wenn du den "key" möchtest, dann frag die datenbank halt danach!
Soll ich bilder von der DB machen, dass das vlt. verständlicher wird?
ich glaub ich kann auch echt schwer erklären ^-^
versuch ist es wert - solange es eine testdatenbank ist!?
zeige mir beide tabellen und sage mir, was du brauchst!
Bilder bitte löschen - auch ein Hash-Passwort kann man decodieren!
Ich habe keinen Primary-Key gesehen ... ohne den, kannst Du das nichtmal mit Join lösen ... und was Du abfragen möchtest, weiß ich auch noch nicht.
Das passwort wird mehrmals geteilt das widerum gehashed und wieder zsm. gefügt und nochmals gehast und jeweils mit sha512.
Bei der Tabelle Users ist der Primary-Key User_TOKEN und bei Infos Info_TOKEN.
Ich möchte eig. ein einfaches SQL Statement(ohne Join wenn es geht) so wie ich es in der Frage dachte, sodass ich aus der Tabelle Infos die passenden User infos, die zu dem User gehören, auslesen kann.
geht das auch in einem SQL Statement wenn ich schon aus der Tabelle Users was selektieren will?
SELECT * FROM Users, Infos WHERE Users.User_TOKEN = "PMgzdI3T9ji-8waSGUJCfTp-IQBT061TIRF-YqSHuMRN4Zk-fS09BDov27l-D0lK2" AND Infos.Info_TOKEN = Users.User_TOKEN
Diese Statement liefert mir ein leeres Resultat. Oder ist hier dran etwas falsch?
nö - sieht eigentlich alles OK aus :-)
dann hast dich vertippt oder die datenbank ist falsch formatiert. sting vs. char zb.
bei den Primary-Keys habe ich varchar benutzt? soll das eher char sein?
das ist mickey-mouse und kindergarten! :)
2 prim-k sind voraussetzung und dann brauchst 2 id-einträge. dann die einfachste abfrage, die in sql möglich ist!
keine ahnung, was du gemacht hast, dass das bei dir nicht funktioniert! das ist von außen schwer zu beurteilen.
phpmyadmin, heidisql, php?! ohne infos kann ich dir nicht helfen und hier würde das auch den rahmen sprengen - sorry.
ich habe mir mühe gegeben und wollte dir helfen ... ehrlich!
sorry - kann ich wohl nicht :-(
ja alles gut. wenn es selber nicht ganze Tabelle die mann macht versteht wird es halt schwierig ^^
Also ein Primärschlüssel ist meistens ein INT, oder eine sonstige Ganzzahl. Ein VARCHAR als Primärschlüssel ist evtl dann sinnvoll, wenn man einen natürlichen Primärschlüssel nimmt, etwa ein KFZ-Kennzeichen oder eine Personalausweisnummer. Oder auch dann, wenn man einen zusammengesetzten Primärschlüssel aus zwei Werten nimmt, die einzeln betrachtet zwar nicht eindeutig sind, zusammen aber schon.
In MySQL ist VARCHAR aber weiter verbreitet als CHAR das ist schon okay.
ich würde es immer mit join machen , mysql ist nicht sql .
du hast keine automatischen relationen wie bei SQL
sondern muss mit LEFt JOIN , OUTER JOIN etc und ON die realtionen selber herstellen .
Man hat bei SQL automatisch Relationen? Das wäre mir neu. Vor allem wäre es unsinnig. Wie soll das denn gehen? Woher soll denn die Datenbank wissen, was sie wie verknüpfen soll?
ich hab mich falsch ausgedrückt, ich schreib es nochmal neu
das mit dem * habe ich jetzt nur genommen damit das vereinfach da gestellt wird, weil ich brauche paar mehr spalten um die 15 und dann alle mit namen hier zu erwähnen.
Ja nur ich kenne die Struktur leider nicht deswegen frage ich ja grad hier ^^
Nein das wollte ich nicht, dachte nur weil in der Tabelle Relationen drin sind geht das ^^