Hallo Markus,
Tabelle: geschaeft
+-------+--------+---------+
| ge_id | art_id | ge_name |
+-------+--------+---------+
| 1 | 4 | Hallo |
| 2 | 2 | Test |
+-------+--------+---------+Tabelle: rating
+-------+--------+---------+
| ge_id | usr_id | ra_wert |
+-------+--------+---------+
| 1 | 3 | 4 |
| 1 | 7 | 2 |
| 2 | 5 | 1 |
+-------+--------+---------+Bei meiner Datenbankabfrage versuche ich die ge_id und die art_id auszulesen, von z.B. Geschäften mit einer durchschnittlichen Bewertung von größer gleich als 3 Sternen.
Das ist doch gar kein Problem :-)
1. Schritt: Join der beiden Tabellen:
SELECT -- Gib mir
g.ge_id, -- die ID der Geschäfte,
g.art_id, -- ihre Art,
g.ge_name, -- ihren Namen und
r.usr_id, -- den Benutzer, der eine Bewertung vorgenommen hat und
r.ra_wert -- die Bewertung
FROM -- aus den Tabellen
geschaefte g -- geschaefte
-- Aliasnamen zum besseren Zugriff auf die Tabellen
INNER JOIN -- die mit der Tabelle
rating r -- rating (der Bewertungen)
ON -- über die Bedingung
g.ge_id = r.ge_id -- gleicher ge_id verknüpft ist
Ergebnis:
+-------+--------+---------+--------+---------+
| ge_id | art_id | ge_name | usr_id | ra_wert |
+-------+--------+---------+--------+---------+
| 1 | 4 | Hallo | 3 | 4 |
| 1 | 4 | Hallo | 7 | 2 |
| 2 | 2 | Test | 5 | 1 |
+-------+--------+---------+--------+---------+
2. Schritt:
Gib mir die Geschäfte samt durchschnittlicher Bewertung.
Die Benutzer-Id interessiert beim Mittelwert nicht mehr.
SELECT
g.ge_id,
g.art_id,
g.ge_name,
AVG(r.ra_wert) AS rating
-- Achtung, Aggregatsfunktion, daher GROUP BY erforderlich
-- es muss nach allen anderen Spalten gruppiert werden
FROM
geschaefte g -- Aliasnamen zum besseren Zugriff auf die Tabellen
INNER JOIN
rating r
ON
g.ge_id = r.ge_id
GROUP BY
g.ge_id,
g.art_id,
g.ge_name
Ergebnis:
+-------+--------+---------+--------+
| ge_id | art_id | ge_name | rating |
+-------+--------+---------+--------+
| 1 | 4 | Hallo | 3 |
| 2 | 2 | Test | 1 |
+-------+--------+---------+--------+
3. Schritt:
Du möchtest nur die haben, deren Mittelwert größer gleich 3 ist.
Dazu ist die HAVING-Klausel zuständig:
SELECT -- Gib mir
g.ge_id, -- die ID der Geschäfte
g.art_id, -- ihre Art (direkt von der ge_id abhängig)
g.ge_name, -- ihren Namen (direkt von der ge_id abhängig)
AVG(r.ra_wert) AS rating
-- und den Durchschnitt ihrer Bewertungen
-- Achtung, Aggregatsfunktion, daher GROUP BY erforderlich
-- es muss nach allen anderen Spalten gruppiert werden
FROM -- aus der Tabelle
geschaefte g -- geschaefte, die über den Aliasnamen g angesprochen wird
INNER JOIN -- und verknüpft ist mit der Tabelle
rating r -- rating, die über r angesprochen wird
ON -- mit der Bedingung
g.ge_id = r.ge_id -- dass die ge_id-Werte übereinstimmen
GROUP BY -- gruppiert, d.h. je Gruppe nur ein Wert, nach
g.ge_id, -- Identifikation des Geschäfts
g.art_id, -- Art des Geschäfts
g.ge_name -- Name des Geschäfts
HAVING -- wobei die durchschnittliche Bewertung mindestens den
rating >= 3 -- Wert 3 haben muss
-- Du kannst hier auch einen Aliasnamen verwenden im
-- Gegensatz zur WHERE-Klausel, die dies nicht erlaubt.
liefert das gewünschte Ergebnis:
+-------+--------+---------+--------+
| ge_id | art_id | ge_name | rating |
+-------+--------+---------+--------+
| 1 | 4 | Hallo | 3 |
+-------+--------+---------+--------+
Überhaupt keine Subselects nötig, liefe sogar unter MySQL 3.23 :-)
Zur HAVING-Klausel gibt es einen Artikel in SELFHTML aktuell:
Datensätze gruppieren mit SQL.
Freundliche Grüße
Vinzenz