Nein, dann ist nichts doppelt, aber ich frage mich gerade warum g.group_name leer ist.
Du meinst eine zweite Abfrage pro Zeile? Das finde ich etwas heftig bei 20-30 Zeilen pro Seite.
EDIT:
Ich habe mal geschaut. Wenn ich DISTINCT UND GROUP BY weglasse, dann sehe ich das Problem denke ich.
Diese Zeile sorgt dafür, dass jedes Mitglied exakt 12 Mal erscheint:
Code: Alles auswählen
LEFT JOIN (groups ug, users g) ON u.uid = ug.uid AND ug.gid = g.uid
Hier noch mal die komplette Abfrage, die ich beim Testen genommen habe:
Code: Alles auswählen
SELECT u.uid, u.gender, u.username, g.group_name, c.message
FROM contacts c, users u
LEFT JOIN (groups ug, users g) ON ug.uid = u.uid AND ug.gid = g.uid
WHERE c.uid = 1
AND c.cid = u.uid
AND c.uagree = 1
ORDER BY u.username ASC
Das dürfte eigentlich nicht sein, da jedes Mitglied nur so oft erscheinen müsste, wie es in Gruppen ist.
Wenn ich übrigens "(groups ug, users g)" umdrehe in "(users g, groups ug)", dann erscheint jedes Mitglied 41 Mal. Und wenn ich bei dem LEFT JOIN "AND g.group_name <> NULL" hinzufüge, dann verschwinden die Zeilen, wo der Name vorhanden ist und nur die NULL Zeilen bleiben. Auch sehr komisch.
EDIT2:
Einfacher als ich dachte, konnte ich die Anzahl der Reihen reduzieren:
Code: Alles auswählen
SELECT u.uid, u.gender, u.username, p.hobby, pic.pid, pic.ext, g.group_name, c.message
FROM contacts c, users u
LEFT JOIN pics pic ON pic.uid = c.cid
LEFT JOIN groups ug ON ug.uid = u.uid
LEFT JOIN users g ON ug.gid = g.uid
LEFT JOIN profiles p ON p.user_id = u.uid
AND p.lang_id =1
WHERE c.uid =1
AND c.cid = u.uid
AND c.uagree =1
ORDER BY u.username ASC
Hier kommt das Ergebnis ohne doppelte Namen raus. Auch wenn ich GROUP_CONCAT() nutze.
Aber das liegt nur daran, dass ich profiles mit "lang_id" auf ein Ergebnis reduziere.
Das ist aber falsch. Denn wenn ich z.B. einen englischsprachigen User anschaue und meine Sprache ist Deutsch, dann werde ich keine Hobbys sehen. Daher müsste es eigentlich so sein "WENN lang_id = meine Sprache vorhanden, dann nehmen, SONST lang_id = Hauptsprache des Profilbesitzers"
Das funktioniert dann aber nicht mehr bei der Suche. Bei der Suche möchte ich in allen Profilen gleichzeitig suchen. Das funktioniert super, aber nur, wenn er in einem Profil was findet. Wenn er ein Wort in zwei Profilen eines Users findet, dann erscheinen die Vereine wieder doppelt. z.B. das Wort "Skaten" könnte sowohl im deutschen als auch englischen Profil des Nutzers vorkommen und schon ist es passiert.
D.h. ich brauche eine Sortierungs- und Limitierungsmöglichkeit.
Perfekt wäre das:
1.) Findet er nichts, dann die Sprache des Anwenders ausgeben (lang_id = 1 z.B. für Deutsch)
2.) Findet er in beiden Ergebnissen etwas, dann soll das angezeigt werden, was wahrscheinlicher ist (die Reihenfolge müsste bereits durch die Volltextsuche vorgenommen sein)
Punkt 2 funktioniert ja im Endeffekt schon. Denn bei der Ausgabe erscheinen die Hobbys, die sich mit der Sucheingabe eher decken. Aber ich sehe daran, dass die Gruppen der Person doppelt angezeigt werden, dass das Suchwort auch in seinem anderssprachigen Profil vorhanden gewesen sein muss. Also müsste ich für Punkt 2 ein LIMIT haben.
Punkt 1 dagegen wäre eine Art IF Geschichte in meinen Augen, womit ich mich ehrlich gesagt gar nicht auskenne
EDIT3:
Hier die Abfrage bei der Suche. Derzeit erhalte ich dabei 2 Ergebnisse, weil User ID 8 zwei Profile angelegt hat:
Code: Alles auswählen
SELECT u.uid, u.gender, u.username, u.group_name AS groupname, p.hobby, u.dob, g.group_name
FROM users u
LEFT JOIN groups ug ON ug.uid = u.uid
LEFT JOIN users g ON ug.gid = g.uid
LEFT JOIN profiles p ON p.user_id = u.uid
WHERE u.active = 1
AND u.uid = 8
EDIT4:
Ich habe mal eine IF Bedingung versucht:
Code: Alles auswählen
SELECT u.uid, u.gender, u.username, u.group_name AS groupname, p.hobby, u.dob, IF( p.lang_id =1, g.group_name, '')
FROM users u
LEFT JOIN groups ug ON ug.uid = u.uid
LEFT JOIN users g ON ug.gid = g.uid
LEFT JOIN profiles p ON p.user_id = u.uid
WHERE u.active =1
AND u.uid =8
Dann erhalte ich zwar immer noch zwei Zeilen, aber die zweite Gruppenname bleibt leer.
Wenn ich das erweitere auf:
Code: Alles auswählen
SELECT u.uid, u.gender, u.username, u.group_name AS groupname, p.hobby, u.dob, IF( p.lang_id =1, g.group_name, IF( p.lang_id =2, g.group_name, '' ) )
Dann erhalte ich wieder beide Ergebnisse, da beim ersten Durchlauf die erste Bedingung greift und beim zweiten die erste verfehlt und dann die zweite greift. So habe ich dann wieder zwei Ergebnisse mit zwei Gruppennamen.
Ich müsste es irgendwie so machen, dass wenn die erste lang_id gefunden wurde, dass er dann aufhört zu suchen.
EDIT5:
Selbst wenn ich p.user_id in GROUP BY nehme erscheinen die Gruppen doppelt. Wenn ich GROUP_CONCAT() aber weglasse erhalte ich nur eine Zeile:
Code: Alles auswählen
SELECT DISTINCT(u.uid), u.gender, u.username, u.group_name AS groupname, p.hobby, u.dob, GROUP_CONCAT( '<a href="./?p=groups&gid=', g.uid, '">', g.group_name, '</a>' ORDER BY g.group_name SEPARATOR ', ' ) group_name
FROM users u
LEFT JOIN groups ug ON ug.uid = u.uid
LEFT JOIN users g ON ug.gid = g.uid
LEFT JOIN profiles p ON p.user_id = u.uid
WHERE u.active = 1
AND u.uid = 8
GROUP BY p.user_id, u.uid
EDIT6:
So damit erhalte ich nun alle Mitglieder sortiert nach ihrem Anmeldedatum und dank DISTINCT im GROUP_CONCAT() auch nur einmal die Vereine:
Code: Alles auswählen
SELECT u.uid, u.gender, u.username, u.group_name AS groupname, p.hobby, u.dob, pic.pid, pic.ext, GROUP_CONCAT(DISTINCT '', g.group_name, '' ORDER BY g.group_name SEPARATOR ', ' ) group_name
FROM users u
LEFT JOIN pics pic ON pic.uid = u.uid
LEFT JOIN groups ug ON ug.uid = u.uid
LEFT JOIN users g ON ug.gid = g.uid
LEFT JOIN profiles p ON p.user_id = u.uid
WHERE u.active = 1
AND u.uid <> 1
GROUP BY u.uid
ORDER BY u.regtime DESC
LIMIT 200
Jetzt brauche ich nur noch etwas, mit dem ich die Reihenfolge aus "LEFT JOIN profiles p ON p.user_id = u.uid" so beeinflussen kann, dass nur lang_id = X (meine Sprache) und dann lang_id = Y (Sprache des Users) ausgelesen wird, wobei meine Sprache als erstes ausgegeben werden soll.
Da ich ja nur eine Zeile Dank "GROUP BY u.uid" erhalte, so würde ich immer erst meine Sprache sehen, sofern der User ein Profil in meiner Sprache angelegt hat.
Wenn ich folgendes mache beeinflusst das leider nicht die Reihenfolge im Ergebnis:
Code: Alles auswählen
SELECT p.lang_id, u.uid, u.gender, u.username, u.group_name AS groupname, p.hobby, u.dob, g.group_name
FROM users u
LEFT JOIN groups ug ON ug.uid = u.uid
LEFT JOIN users g ON ug.gid = g.uid
LEFT JOIN profiles p ON p.user_id = u.uid AND (p.lang_id = 2 OR p.lang_id = 1)
WHERE u.active =1
AND u.uid <>1
AND u.uid = 8
ORDER BY u.regtime DESC
LIMIT 200
Die erste Zeile ist lang_id 1 und die zweite Zeile lang_id 2. Denkt dran, ein ORDER BY hilft hier nicht, da ich nicht weiß, welche lang_ids da stehen könnten. Da könnte jetzt auch lang_id 8 (meine) und lang_id 4 (seine) gesucht sein.
Beispiel wie es in der Datenbank gespeichert wurde ohne Sortierung:
1
2
3
4
5
Ich will zuerst 5 und dann 3, Rest ist mir egal:
5
3
Wie könnte man etwas so auslesen?
Gruß
EDIT7:
Ok, super ich denke ich habs. Hier gefunden:
http://mysql-faq.sourceforge.net/anwendung2.html
Code: Alles auswählen
SELECT p.lang_id, u.uid, u.gender, u.username, u.group_name AS groupname, p.hobby, u.dob, g.group_name
FROM users u
LEFT JOIN groups ug ON ug.uid = u.uid
LEFT JOIN users g ON ug.gid = g.uid
LEFT JOIN profiles p ON p.user_id = u.uid
WHERE u.active =1
AND u.uid <>1
AND u.uid =8
ORDER BY u.regtime DESC , p.lang_id <> 2, p.lang_id <> 1
LIMIT 200
War ORDER BY doch der richtige Ansatz
