SQL Abfrage LEFT JOIN
Chrisi
- datenbank
Hallo zusammen,
ich beisse mir an einer kleinen Abfrage irgendwie die Zähne aus:
SELECT *
FROM user AS u LEFT JOIN pictures ON u.UID = pictures.UID
WHERE pictures.UID IS NOT NULL
Hier eght es um 2 Tabellen, die eine enthält die Userdaten die andere enthält wenn vorhanden Fotos von den Usern. Nun möchte ich nur die User aus der DB holen die auch mindestens 1 Foto bzw. einen Datensatz in der Tabelle pictures hinterlegt haben.
Meine Abfrage oben scheint eine Endschleife zu produzieren, da Sie keine Fehlermeldung und auch kein Resultat bringt, der Browser hängt sich quasie auf *g* ...
Weis vieleicht jemand hier was ich da oben falsch mache ?
Danke und Grüße, Chrisi ...
echo $begrüßung;
Meine Abfrage oben scheint eine Endschleife zu produzieren, da Sie keine Fehlermeldung und auch kein Resultat bringt, der Browser hängt sich quasie auf *g* ...
Browser führen im Allgemeinen keinen SQL-Code aus. Es mag sein, dass eine DB-Abfrage mal etwas längert dauert, besonders wenn man keine Indexe gesetzt hat, aber an ein Aufhängen glaube ich nicht.
Ich vermute den Fehler eher im Script, das diese SQL-Abfrage enthält.
Läuft die Abfrage denn in phpMyAdmin oder vergleichbaren Tools?
echo "$verabschiedung $name";
Hi,
ich habe die Abfrage gerade mal im MySQL query Browser laufen lassen, nach ca. 120 Sekunden kommen dann die ersten Ergebnisse ...
Die Spalten UID sind in allen Tabellen primary Key, autoincrement und numerisch, macht es da denn überhaupt Sinn wenn ich einen Index drüber lege ? BZW. ist das zulässig ?
Danke u. viele Grüße, Chrisi
Sorry ich habe mich vertan.
UID ist nur in user primary u. autoincrement.
In den anderen Tabellen ist UID nur numerisch, ich habe jetzt mal zum testen einen Index über pictures.UID gelegt, dadurch geht die Abfrage in ca. 1 sec durch.
Nun bleibt nurnoch die Frage ob das zulässig o. richtig ist :)
Viele Grüße, Chrisi
echo $begrüßung;
In den anderen Tabellen ist UID nur numerisch, ich habe jetzt mal zum testen einen Index über pictures.UID gelegt, dadurch geht die Abfrage in ca. 1 sec durch.
Also doch nix mit Aufhängen, das war nur Ungeduld :-)
Nun bleibt nurnoch die Frage ob das zulässig o. richtig ist :)
Alles was keinen Syntaxfehler erzeugt ist zulässig.
Das U in UID [*] steht doch für Unique. Und damit die DB garantieren kann, dass die Werte in der Spalte wirklich einmalig sind, müsstest du da schon einen Unique-Index drüberlegen, oder einen Primary Key, der von Haus aus schon unique ist.
echo "$verabschiedung $name";
[*] U-ID ist doppelt gemoppelt, sowas wie weißer Schimmel. Ein Identifier muss einmalig sein, sonst eignet er sich nicht zum Identifizieren.
Hi,
[*] U-ID ist doppelt gemoppelt, sowas wie weißer Schimmel. Ein Identifier muss einmalig sein, sonst eignet er sich nicht zum Identifizieren.
Das verstehe ich jetzt nicht :)
UID ist in der Tab user Unique, aber in der Tab pic darf er mehr als einen Eintrag haben und dient als Erkennungsmerkmal um die pics den usern zuordnen zu können.
Ich habe aber auch noch andere Tabs in denen jede UID nur einen Datensatz haben darf, dass sind dann die Erweiterten Daten zu einem User, wie z.B. Interessen und Eigenschaften etc ...
Also wenn ich jetzt deine Info richtig deute:
Soll die Tab mehr als einen Datensatz zu einem User (UID) enthalten ist UID "nur" ein Index.
Soll die Tab aber nur einen Datensatz zur UID enthalten, so kann Sie die UID als primary Key und damit gleich als Unique und Index festlegen ? ALso brauche ich hier eigentlich garkeinen "extra" primary Key für jeden Datensatz, sondern kann diese ja anhand der UID fest zurordnen und einfach dort einen primary setzen ...
Zur Erläuterung:
Alle meine Tabellen haben immer in der ersten Spalte eine id Spalte in der die Datensatz ID mit primary u. autoincrement gesetzt wird.
Deine Info sagt mir jetzt das ich mir bei den Tabellen die sowieso immer nur einen Datensatz zu UID enthalten dürfen die "extra" Spalte mit der ID sparen kann u. einen primary über die Splate UID lege kann. Habe ich das so richtig verstanden ?
Klingt jetzt für mich soweit sehr logisch, werde das ganze dann wohl auch in meinem DB Design umbauen ...
Viele Grüße, Chrisi ...
echo $begrüßung;
UID ist in der Tab user Unique, aber in der Tab pic darf er mehr als einen Eintrag haben und dient als Erkennungsmerkmal um die pics den usern zuordnen zu können.
Ich nahm an, dass das U in UID für Unique steht. Wenn es aber für User steht, dann ist natürlich meine Fußnote nicht mehr zutreffend. Wie dem auch sei...
Ich habe aber auch noch andere Tabs in denen jede UID nur einen Datensatz haben darf, dass sind dann die Erweiterten Daten zu einem User, wie z.B. Interessen und Eigenschaften etc ...
Wenn die Daten sowieso nur eine 1:1-Beziehung haben sehe ich erstmal keine Notwendigkeit, sie in mehrere Tabellen aufzuteilen.
Deine Info sagt mir jetzt das ich mir bei den Tabellen die sowieso immer nur einen Datensatz zu UID enthalten dürfen die "extra" Spalte mit der ID sparen kann u. einen primary über die Splate UID lege kann. Habe ich das so richtig verstanden ?
Wenn du unbedingt die 1:1-Daten aufteilen willst, dann hast du mit dem UID ja schon einen eindeutigen Identifier zum gezielten Ansprechen eines einzeilnen Datensatzes.
Klingt jetzt für mich soweit sehr logisch, werde das ganze dann wohl auch in meinem DB Design umbauen ...
Wenn du möchtest, kannst du ja mal hier aufführen, welche Daten du zu sammeln gedenkst und in welcher Beziehung die zueinander stehen sollen. Wer weiß, was noch alles umbauwürdig ist :-)
echo "$verabschiedung $name";
Hi,
Wenn du möchtest, kannst du ja mal hier aufführen, welche Daten du zu sammeln gedenkst und in welcher Beziehung die zueinander stehen sollen. Wer weiß, was noch alles umbauwürdig ist :-)
Also eine Aufteilung ist glaube ich absolut notwendig, für eine Tabelle wäre es zuviel. Hier das Schema mit den neuen primarys:
-> user = UID,username,passwort,email u.s.w...
soweit logisch ...
-> character = UID,look,size,weight,figure u.s.w... alles ENUM()
Mögliche Werte die unter ENUM() festgelegt werden
z.B. look = ENUM('egal','geht so','gut','sehr gut')
-> interests = UID,1,2,3,4,5 u.w.s... numeric 1-5
1 = Kino, Skala von 1-5 wobei 1 = schlecht 5 = sehr gut
Die Splatennamen habe ich hier bewusst auf Zahlen begrenzt um die
DB und Scripte dann übertragbar auf andere Projekte zu machen.
Z.B. könnte Spalte 1 bei einem anderen Projekt für "Reiten"
stehen anstatt für "Kino".
-> pictures = id,UID,picname,status
Userpics (mehr als eines) soweit logisch, hier habe ich aber
die id(primary) gelassen um schnell auf einen Datensatz zugreifen
zu können, zb. zum löschen.
Alle 4 Tabellen haben insgesamt ca. 50 Spalten, die Aufteilung ist soweit logisch, da die Informationen die in die Tabellen kommen auch in verschiedenen Schritten aufgenommen werden.
Das ganze ist eine Art Datingdatenbank :)
Viele Grüße, Chrisi ...
Hallo Chrisi
Also eine Aufteilung ist glaube ich absolut notwendig, für eine Tabelle wäre es zuviel. Hier das Schema mit den neuen primarys:
-> user = UID,username,passwort,email u.s.w...
soweit logisch ...
-> interests = UID,1,2,3,4,5 u.w.s... numeric 1-5
1 = Kino, Skala von 1-5 wobei 1 = schlecht 5 = sehr gut
Die Splatennamen habe ich hier bewusst auf Zahlen begrenzt um die
DB und Scripte dann übertragbar auf andere Projekte zu machen.
Z.B. könnte Spalte 1 bei einem anderen Projekt für "Reiten"
stehen anstatt für "Kino".
Hier solltest Du umbauen, da eine m:n-Beziehung vorliegt:
Jeder "user" kann mehrere "interests" (kann sich lohnen, wenn der Zinssatz hoch genug ist *g*) haben. Jedem "interest" können mehrere "user" zugeordnet sein. Typischerweise löst Du so etwas über drei Tabellen auf, von denen Du eine bereits hast:
Tabelle user (Benutzerdaten)
Tabelle interests (verschiedene Interessensgebiete)
Tabelle user_interests (oder so ähnlich): Zuordnungstabelle
Es reicht aus, als Primärschlüssel dieser Tabelle die Kombination der Spalten uid, iid zu nehmen, da diese Kombination eindeutig sein muss. Auf diesen Spalten sollte sowieso ein kombinierter eindeutiger Index liegen, damit Fehler vermieden werden: Einer Person kann nicht zweimal das gleiche Interessensgebiet zugeordnet werden.
-> character = UID,look,size,weight,figure u.s.w... alles ENUM()
Mögliche Werte die unter ENUM() festgelegt werden
z.B. look = ENUM('egal','geht so','gut','sehr gut')
Auch hier empfehle ich Dir aus Gründen der Flexibilität eine andere Tabellenstruktur: Wenn Dir eine weitere Eigenschaft einfällt, so musst Du Deine Tabellenstruktur durch Einfügen einer weiteren Spalte einfügen. Viel besser ist es, wenn Du eine weitere Zeile in einer bereits vorhandenen Tabelle anfügen kannst. Geht das? Ja, es geht:
Jede Person kann mehrere verschiedene Wunscheigenschaften angeben.
Jede Wunscheigenschaft kann von mehreren Personen angegeben werden.
Du hast schon wieder eine n:m-Beziehung, die Du analog zur vorhin behandelten Tabelle auflösen kannst.
Tabelle user (bereits vorhanden)
Tabelle characters
Tabelle user_charakters
-> pictures = id,UID,picname,status
Userpics (mehr als eines) soweit logisch, hier habe ich aber
die id(primary) gelassen um schnell auf einen Datensatz zugreifen
zu können, zb. zum löschen.
Wie wäre es mit pid, da es ja ein "picture" identifiziert. Das ist meiner Meinung nach aussagekräftiger als id.
Das ganze ist eine Art Datingdatenbank :)
Ach nee ...
Da wäre nie jemand darauf gekommen. *g*
Freundliche Grüße
Vinzenz
Hi Vinzenz,
danke für deine Hilfe, von der Seite habe ich das ganze noch nie betrachtet und eröffnet mir neue Möglichkeiten.
Hier solltest Du umbauen, da eine m:n-Beziehung vorliegt:
Jeder "user" kann mehrere "interests" (kann sich lohnen, wenn der Zinssatz hoch genug ist *g*) haben. Jedem "interest" können mehrere "user" zugeordnet sein. Typischerweise löst Du so etwas über drei Tabellen auf, von denen Du eine bereits hast:
Ich habe das Stück Text ca. 5 mal gelesen, habe aber den Verdacht das ich nicht verstanden habe wie du das meinst :)
Ich würde jetzt so umbauen:
Tabelle interests ->
IID -> Ident des Datensatzes (Primary)
UID -> UserID (Index)
interest -> ENUM('kino','tv','fussball','computer','chatten')
scala -> ENUM('1','2','3','4','5')
Aber ich glaube deine Theorie geht tiefer, du verwendest anstatt ENUM bei interest eine extra Tabelle ?
Danke aufjedenfall für die Tipps !
Viele Grüße, Chrisi ...
Hallo Chrisi
ich habe die Abfrage gerade mal im MySQL query Browser laufen lassen, nach ca. 120 Sekunden kommen dann die ersten Ergebnisse ...
Was steht denn in Deinen Spalten drin? Benötigst Du diese auch alle? SELECT * gilt es im Allgemeinen zu vermeiden.
Die Spalten UID sind in allen Tabellen primary Key, autoincrement und numerisch, macht es da denn überhaupt Sinn wenn ich einen Index drüber lege ? BZW. ist das zulässig ?
Eine Spalte, die alleiniger Träger des Primärschlüssels ist, ist stets mit einem unique-Index versehen, also erübrigt sich das Erstellen eines weiteren Index.
Eine weitere Anmerkung:
Du solltest einfach Deinen LEFT OUTER JOIN durch einen INNER JOIN ersetzen. Denn der liefert Dir genau, was Du willst:
SELECT
u.spalte1,
u.spalte2,
...
FROM user AS u
INNER JOIN pictures ON u.UID = pictures.UID
Freundliche Grüße
Vinzenz
Hi,
Was steht denn in Deinen Spalten drin? Benötigst Du diese auch alle? SELECT * gilt es im Allgemeinen zu vermeiden.
OK, schon an unf fuer sich ein nachvollziehbarer Gedankengang. Allerdings - in Zeiten von XML - nicht mehr so ueberzeugend wie "frueher".
Horizontale und vertikale Filterungen "auf Matrices" sind OK, aber, nicht nur fuer Test- und Schemaabfragen, mag eine nichterfolgte horizontale Filterung durchaus Sinn ergeben.
Gerade auch um Code am Start zu haben, der fuer Entitaeten alle verfuegbaren Attribute und deren Werte liefert z.B.. "Code fuer die Ewigkeit" so zu sagen.
Aber klar, das ist Ideologie.
Gruss,
Ludger