Benutzer:Vinzenz/Spielwiese

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
Hinweis:

Entwurf für einen Datenbankartikel

Hinweis:
Artikelüberschrift ausdenken

Problemstellung

Hinweis:
Problem hinreichend vernünftig beschreiben, die Überschrift von asmodin ist bisher das Beste

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
Hinweis:
Abfrageergebnisse einfügen

Schritt 1

Beispiel
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

Beispiel
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:

Beispiel
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.


Beachten Sie: Standard-SQL läßt in der HAVING-Klausel die Verwendung von Spaltenaliasnamen nicht zu, deswegen wird hier die Berechnungsformel wiederholt. Falls Sie MySQL verwenden, könnten Sie in der HAVING-Klausel auch den Spaltenaliasnamen verwenden.

Schritt 4: Weglassen der nur zur Berechnung erforderlichen Spalte

Beispiel
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.


Hinweis:
Anmerkungen zu alternativen Lösungswegen wie Subselect, Selfjoin. Erweiterungen der Fragestellung.