Frage von MarkusNow99, 157

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.

Antwort
von wotan38, 49

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)



Antwort
von Alextoexplain, 46

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

Antwort
von PeterP58, 62

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!

Kommentar von MarkusNow99 ,

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 ^^

Kommentar von PeterP58 ,

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";
Kommentar von MarkusNow99 ,

aber der tab_2.info.key bekomme ich erst du die spalte in der Users tabelle die da hinterlegt ist

Kommentar von PeterP58 ,

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!

Kommentar von MarkusNow99 ,

Soll ich bilder von der DB machen, dass das vlt. verständlicher wird?

ich glaub ich kann auch echt schwer erklären ^-^

Kommentar von PeterP58 ,

versuch ist es wert - solange es eine testdatenbank ist!?

zeige mir beide tabellen und sage mir, was du brauchst!

Kommentar von MarkusNow99 ,

https://uploads.klassen-manager.com/DB/

da sind die beiden Tabellen und die Relation

Kommentar von PeterP58 ,

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.

Kommentar von MarkusNow99 ,

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.

Kommentar von PeterP58 ,

"Where Info_TOKEN= User_Info-TOKEN"

ist dann das, was Du suchst! :)

Kommentar von MarkusNow99 ,

geht das auch in einem SQL Statement wenn ich schon aus der Tabelle Users was selektieren will?

Kommentar von PeterP58 ,

einfach in die query dranhängen... "AND WHERE ..."

Kommentar von MarkusNow99 ,
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?

Kommentar von PeterP58 ,

nö - sieht eigentlich alles OK aus :-)

dann hast dich vertippt oder die datenbank ist falsch formatiert. sting vs. char zb.

Kommentar von MarkusNow99 ,

bei den Primary-Keys habe ich varchar benutzt? soll das eher char sein?

Kommentar von PeterP58 ,

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.

Kommentar von MarkusNow99 ,

ja ok. aber trotzdem vielen dank :)

Kommentar von PeterP58 ,

ich habe mir mühe gegeben und wollte dir helfen ... ehrlich!

sorry - kann ich wohl nicht :-(

Kommentar von MarkusNow99 ,

ja alles gut. wenn es selber nicht ganze Tabelle die mann macht versteht wird es halt schwierig ^^

Kommentar von Alextoexplain ,

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.

Antwort
von RakonDark, 27

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 .

Kommentar von Alextoexplain ,

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?

Kommentar von RakonDark ,

ich hab mich falsch ausgedrückt, ich schreib es nochmal neu

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten