Vinzenz Mai: Errata

Beitrag lesen

Hallo,

um diese Zeit sollte ich keine Beiträge mehr schreiben. Der Weg ist in Ordnung, die Statements sind es nicht, einer Optimierung und C&P sei Dank.

Nehmen wir folgendes Beispiel
table_mapping:

mapping_id | page_id | visitor_id | created

1 |       1 |         2  | egal
         2 |       1 |         2  | auch
         3 |       2 |       111  | erst
         4 |       2 |        10  | recht
         5 |       2 |         2  | egal
         6 |       3 |        10  | auch
         7 |       1 |       111  | erst
         8 |       4 |        88  | recht
         9 |       3 |         2  | egal
        10 |       2 |        10  | auch

[...] richtiges gestrichen.

Nur diejenigen, die in der Spalte Anzahl eine 2 stehen haben, können beide Seiten (1 und 2) besucht haben. Deswegen können wir diese Ergebnismenge auf die Datensätze einschränken, bei denen Anzahl den Wert 2 aufweist. Anzahl ist das Ergebnis einer Aggregatsfunktion und eine Einschränkung kann deswegen erst nach Ermittlung aller Datensätze mit der HAVING-Klausel erfolgen - und nicht mit der WHERE-Klausel:

SELECT  
    visitor_id,  
    COUNT(DISTINCT page_id) Anzahl  -- wir zählen unterschiedliche page_ids  
                                      -- nicht visitor_ids  
FROM  
    table_mapping  
WHERE  
    page_id IN (1, 2)  
GROUP BY  
    visitor_id                      -- Tabellenalias entfernt  
                                    -- vorher war's komplizierter  
HAVING  
    Anzahl = 2              -- in Standard-SQL darf man hier keinen Alias  
                            -- benutzen, [link:http://dev.mysql.com/doc/refman/5.0/en/problems-with-alias.html@title=MySQL lässt es zu].  

und bekommen das oben geforderte Ergebnis:

visitor_id | Anzahl

2 |     2
       111 |     2

bzw. wenn wir die Anzahl nicht nutzen müssen (weil wir sie sowieso kennen):

SELECT  
    visitor_id  
FROM  
    table_mapping  
WHERE  
    page_id IN (1, 2)  
GROUP BY  
    visitor_id                       -- Tabellenalias entfernt  
HAVING  
    COUNT(DISTINCT page_id) = 2      -- richtige Spalte gezählt  

mit der Ergebnistabelle:

visitor_id

2
       111

Code (copy & paste)-getestet mit MySQL 5.1.41 und MS SQL-Server 2005. Letzterer meckert (korrekt) erstes Statement mit dem Spaltenalias an, so wie es in meinem Kommentar steht ...

Freundliche Grüße

Vinzenz