MySQL Relationship mehrere Tabllen verbinden und in der SQL Query ohne Join selektieren?

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!


MarkusNow99 
Beitragsersteller
 20.12.2015, 16:10

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

PeterP58  20.12.2015, 16:14
@MarkusNow99

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";
MarkusNow99 
Beitragsersteller
 20.12.2015, 16:17
@PeterP58

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

PeterP58  20.12.2015, 16:21
@MarkusNow99

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!

MarkusNow99 
Beitragsersteller
 20.12.2015, 16:24
@PeterP58

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

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

PeterP58  20.12.2015, 16:28
@MarkusNow99

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

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

PeterP58  20.12.2015, 16:43
@MarkusNow99

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.

MarkusNow99 
Beitragsersteller
 20.12.2015, 16:47
@PeterP58

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.

PeterP58  20.12.2015, 16:51
@MarkusNow99

"Where Info_TOKEN= User_Info-TOKEN"

ist dann das, was Du suchst! :)

MarkusNow99 
Beitragsersteller
 20.12.2015, 16:52
@PeterP58

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

MarkusNow99 
Beitragsersteller
 20.12.2015, 16:57
@PeterP58
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?

PeterP58  20.12.2015, 17:06
@MarkusNow99

nö - sieht eigentlich alles OK aus :-)

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

MarkusNow99 
Beitragsersteller
 20.12.2015, 17:09
@PeterP58

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

PeterP58  20.12.2015, 17:12
@MarkusNow99

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.

PeterP58  20.12.2015, 17:23
@MarkusNow99

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

sorry - kann ich wohl nicht :-(

MarkusNow99 
Beitragsersteller
 20.12.2015, 17:26
@PeterP58

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

Alextoexplain  20.12.2015, 21:38
@MarkusNow99

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 .


Alextoexplain  20.12.2015, 21:39

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?