Seite 1 von 1

[MySQL] komme mit JOIN nicht zurecht

Verfasst: 04.11.2006 18:27
von Vincent
also ich schätze mal dass ich für mein problem mit dem join irgendwie was machen muss, aber irgendwie krieg ich das nicht hin

also folgendes:
ich habe drei neue felder im posting-bereich eingerichtet die ihre Daten in die Tabelle: phpbb2_posts_text in die drei Felder: post_prod_rate_1, post_prod_rate_2 und post_prod_rate_3 speichern als Inhalt kommen nur die Zahlen von 0 - 3 in frage, alles andere ist ausgeschlossen.

also jeder der postet (auch antwortet) speichert dort werte ein, für jeden post anders.

jetzt brauch ich eine abfrage die mir die inhalte der drei felder aller posts eines bestimmten topics in drei arrays schreibt.

ich möchte am ende den durchschnittswert eines jeden arrays ausrechnen lassen und ausgeben

kurz mal ein beispiel:

Thema Bewertung für XY hat drei posts (inklusive Topic-Starter)
User 1 bewertet in seinem post
post_prod_rate_1 = 3
post_prod_rate_2 = 2
post_prod_rate_3 = 2

User 2 bewertet in seinem post
post_prod_rate_1 = 2
post_prod_rate_2 = 1
post_prod_rate_3 = 2

User 3 bewertet in seinem post
post_prod_rate_1 = 1
post_prod_rate_2 = 2
post_prod_rate_3 = 3

jetzt brauch in
array1 die werte 3, 2 und 1 in
array2 die werte 2, 1 und 2 und in
array3 die werte 2, 2 und 3

dann wird gerechnet
3 + 2 + 1 = 6
6 / 3 = 2 = Durchschnitt der bewertungen von post_prod_rate_1

mein problem bei der abfrage ist, dass ich die post_id aus

Code: Alles auswählen

SELECT post_id FROM phpbb2_posts WHERE topic_id = $topic_id
mit der post_id aus

Code: Alles auswählen

SELECT post_prod_rate_1, post_prod_rate_2, post_prod_rate_3 FROM phpbb2_posts_text
vergleichen muss damit ich nur die einträge bekomme auch zum jeweiligen topic gehören

ich hoffe ich hab mich jetzt verständlich genug ausgedrückt und jemand hat muse mir zu helfen, danke schon mal im vorraus

cya
Vinc

Verfasst: 04.11.2006 19:16
von gn#36
Ich denke das mit den Arrays ist gar nicht nötig, es gibt bereits vorgefertigte SQL Funktionen die das können: SUM(tabellenspalte), ROUND(Wert,Stellenzahl) und COUNT(tabellenspalte).
Wenn du den Durchschnitt der "spalte_eins" haben willst kannst du also z.B. diese Abfrage verwenden:

Code: Alles auswählen

SELECT ROUND(SUM(spalte_eins) / COUNT(spalte_eins), 2) AS avg_spalte_eins FROM tabelle WHERE 1
Jetzt steht der Durchschnitt bereits als Ergebnis der Abfrage zur Verfügung (als avg_spalte_eins) und muss nicht erst berechnet werden.

Ich würde dir außerdem für erweiterte Datenbankkompatibilität raten, die vordefinierten Konstanten für die Tabellen in phpBB zu verwenden, die sich in der constants.php befinden, hier also POSTS_TEXT_TABLE wenn ich mich nicht irre.

Wenn du eine Abfrage von mehreren Tabellen machen willst findest du dazu Beispiele in fast allen PHP Dateien des Forums.

Wenn du ein Join Statement verwenden willst dann musst du allen beteiligten Tabellen Namen geben, damit die Datenbank "weiß" welche Tabellenspalten genau gemeint sind.
Syntax:

Code: Alles auswählen

SELECT a.spalte_eins, b.spalte_zwei FROM tabelle_eins a LEFT JOIN tabelle_zwei b ON a.spalte_drei = b.spalte_drei WHERE a.spalte_vier = 'WERT'
Diese Abfrage selektiert spalte_eins aus der ersten Tabelle und spalte_zwei aus der zweiten, wobei die beiden anhand spalte_drei abgeglichen werden und außerdem nur Einträge berücksichtigt werden, die in der spalte_vier von tabelle a 'WERT' stehen haben. Bei deinem Problem sollte das ähnlich funktionieren.

Wenn du die Konstanten aus der constants.php verwendest solltest du das etwa so machen:

Code: Alles auswählen

$sql = "SELECT * FROM " . POSTS_TABLE . " WHERE 1";
Hierbei die Leerzeichen vor und nach der Konstante nicht vergessen, sonst gibt es eine Fehlermeldung.

Verfasst: 04.11.2006 22:07
von Vincent
big THX @ gn#36

hat zwar jetzt gut 1,5 h gebraucht bis ich schlussendlcih durchgestiegen bin, aber jetzt klappts und so wies aussieht hab ich das mit den JOINs nu auch kapiert

BTW dass ich die Konstanten für Tabellennamen in meinem Post hier nicht verwendet hab hat den grund dass ich solche abfragen grundsätzlich unter phpmyadmin teste, das erspart ne menge upload(traffic) und Zeit, weil meißtens solche (neuartigen) abfragen nicht auf anhieb klappen

in meiner phpbb-Datei dann wird alles so kompatibel geschrieben wies geht (bzw ichs kannXD) trotzdem Danke für alle Hinweise

Verfasst: 04.11.2006 22:58
von Gumfuzi
Muss da passend gleich mal was fragen:

Was ist der Unterschied zw. den beiden Abfragen?

Code: Alles auswählen

SELECT a.spalte_eins, b.spalte_zwei FROM tabelle_eins a LEFT JOIN tabelle_zwei b ON a.spalte_drei = b.spalte_drei WHERE a.spalte_vier = 'WERT'

Code: Alles auswählen

SELECT a.spalte_eins, b.spalte_zwei FROM tabelle_eins a, tabelle_zwei b WHERE a.spalte_drei = b.spalte_drei AND a.spalte_vier = 'WERT'
Welche ist i.d.R. schneller bzw. besser geeignet?

Verfasst: 04.11.2006 23:03
von Olli Oberhausen
Lösung 2 gibt nur dann ein ergebnis aus wenn a.spalte_drei = b.spalte_drei wobei lösung 1 auch dann ein ergebnis (a.spalte_eins, b.spalte_zwei) ausgibt wenn b.spalte_drei nicht zum datensatz passt...

Verstanden? Ich nicht :D

Olli

Verfasst: 05.11.2006 02:49
von S2B
Olli Oberhausen hat geschrieben:Verstanden? Ich nicht :D
Nochmal :D

Beim LEFT JOIN-Query werden immer alle Zeilen aus tabelle_eins zurückgegeben, beim anderen werden hingegen nur die ausgegeben, bei denen entsprechende Werte in tabelle_zwei vorhanden sind.

Zur Performance: Sagen wir mal so: Das LEFT JOIN-Query ist gut, das andere könnte man imho durch ein (INNER) JOIN beschleunigen.

Verfasst: 05.11.2006 08:35
von Gumfuzi
danke für die Erklärung!

Verfasst: 05.11.2006 10:46
von Olli Oberhausen
Ich weiss, du hast es schon verstanden aber ich hab noch ein schönes beispiel aus der index:

Code: Alles auswählen

			$sql = "SELECT f.*, p.post_time, p.post_username, u.username, u.user_id
				FROM (( " . FORUMS_TABLE . " f
				LEFT JOIN " . POSTS_TABLE . " p ON p.post_id = f.forum_last_post_id )
				LEFT JOIN " . USERS_TABLE . " u ON u.user_id = p.poster_id )
				ORDER BY f.cat_id, f.forum_order";
Die forum daten bekommst du immer.
Die user und post daten nur wenn sie existieren.

WHERE => AND würde hier kein Forum anzeigen wenn kein beitrag existieren würde (Ein teufelskreis :grin: )

Olli

Verfasst: 05.11.2006 12:54
von gn#36
Vincent hat geschrieben: BTW dass ich die Konstanten für Tabellennamen in meinem Post hier nicht verwendet hab hat den grund dass ich solche abfragen grundsätzlich unter phpmyadmin teste, das erspart ne menge upload(traffic) und Zeit, weil meißtens solche (neuartigen) abfragen nicht auf anhieb klappen
Kann ich gut verstehen, aber ich teste meine Skripte grundsätzlich sogar lokal (und wenn ich sie nicht zum Laufen kriege weil irgendwas in der SQL Syntax falsch ist, dann eben bei PHPMyAdmin lokal.) Dann brauche ich bei den Tests gar keine Dateien auf den Server hochladen was eine ganze Menge Zeit spart (nur ändern & speichern statt ändern, speichern und hochladen) und wenn dann alles klappt kann es auf den Server. Es gibt ja genügend kostenfreie Webserver die man sich sehr einfach lokal installieren kann (teilweise ist "installieren" das falsche Wort, es besteht mehr aus kopieren und Pfade anpassen).