Benutzer:Vinzenz/Spielwiese
- Am 14.10.2015 wurden die ToDo-Vorlagen in Hinweise umgewandelt.Matthias Scharwies (Diskussion) 16:56, 10. Okt. 2015 (CET)
Entwurf für einen Datenbankartikel
Problemstellung
- Forumsthread "Count aus Mapping-Tabelle (cheops)"
- Forumsthread "SQL-Abfrage (Erhardt)
- Forumsthread "Mehrere Bedingungen über mehrere Datensätze verteilt gruppieren (asmodin)
Beispiel: Welche Besucher haben eine bestimmte Auswahl von Seiten aufgerufen?
Ausgangstabelle "example"
id | seiten_id | besucher
Gesucht sind die Besucher, die die Seiten 1 und 2 aufgerufen haben.
gewünschte Ergebnismenge
Besucher
Beispielhafter Lösungsweg:
- Ermittle die Datensätze, die zu der Auswahl der Seiten passen
- Zähle für jeden Benutzer die unterschiedlichen Seiten, die der Besucher aufgerufen hat
- Schränke die Ergebnismenge auf die Besucher ein, die genausoviele unterschiedliche Seiten aufgerufen haben, wie in der Auswahl enthalten sind
Schritt 1
SELECT
besucher,
seiten_id
FROM
example
WHERE
seiten_id IN (1, 2);
Sie schränken durch die WHERE-Klausel und den IN-Operator die Ergebnismenge auf die Datensätze ein, die die gewünschten Seiten enthalten. Alle anderen Datensätze sind für die Problemstellung nicht von Interesse.
Schritt 2
SELECT
besucher,
COUNT(DISTINCT seiten_id) Anzahl
FROM
example
WHERE
seiten_id IN (1, 2)
GROUP BY
besucher;
Es sollte offensichtlich sein, dass Sie nicht einfach die Datensätze je Benutzer zählen können, weil Benutzer Seiten durchaus mehrfach aufgerufen haben können. Deswegen zählen Sie mit COUNT(DISTINCT)
nur die unterschiedlichen Werte je Benutzer, nach denen Sie mit der GROUP BY
-Klausel gruppieren. Die berechneten Spalte versehen Sie über einen Spaltenalias Anzahl mit einer netten Überschrift.
Schritt 3:
SELECT
besucher,
COUNT(DISTINCT seiten_id) Anzahl
FROM
example
WHERE
seiten_id IN (1, 2)
GROUP BY
besucher
HAVING
COUNT(DISTINCT seiten_id) = 2;
Nur diejenigen Benutzer, die in der Spalte Anzahl eine 2 stehen haben, können beide Seiten (1 und 2) besucht haben. Deswegen können wir die Ergebnismenge aus Schritt 2 auf die Datensätze einschränken, bei denen die berechnete Spalte den Wert 2 aufweist. Die Werte in der Spalte Anzahl sind das Ergebnis einer Aggregatsfunktion und stehen daher erst nach der Ermittlung aller Datensätze zur Verfügung. Die Einschränkung kann daher nicht mit der WHERE-Klausel vorgenommen werden, sondern muss über die HAVING-Klausel erfolgen.
Schritt 4: Weglassen der nur zur Berechnung erforderlichen Spalte
SELECT
besucher
FROM
example
WHERE
seiten_id IN (1, 2)
GROUP BY
besucher
HAVING
COUNT(DISTINCT seiten_id) = 2;
Die berechnete Spalte benötigen Sie nur zur Ermittlung der Ergebnismenge. Den Inhalt dieser Spalte kennen Sie; schließlich verwenden Sie diesen Wert in der HAVING-Klausel. Deswegen können Sie diese Spalte ohne Informationsverlust weglassen, um die vom DBMS zum Client zu transportierende Datenmenge möglichst gering zu halten.