Vinzenz Mai: JOIN 3 Tabellen + Count - Problem

Beitrag lesen

Hallo,

Danke für deine Hilfe,
die in keinster weise für mich einen konstruktiven Punkt darstellt.
ich habe Dir klar gesagt, was ich brauche, um Dir helfen zu können.

Haupttabelle - News:
ID | DEL | Category | Status | Comments | Image | Title | Text | Keywords | User_ID | Timestamp | Clicks | Edit_User | Edit_Date | Edit_Count

Ich würde jetzt gerne alle Einträge aus der Haupttabelle News auslesen,
und die Views und Comments für jeden Eintrag in nur einem Statment
zählen, damit ich die News dann entsprechend Ordnen kann.

Comments - steht hierbei für einen 0 oder 1 Wert ob Kommentare grundsätzlich erlaubt sind.

Tabelle - Comments:
ID | Articel_ID | Author | Title | Text Timestamp | Edit_User | Edit_Date | Edit_Count

Die Articel_ID entspricht der ID der Haupttabelle - News.

Wenn Du ermitteln möchtest, wieviele Einträge es je Articel_ID gibt, so erhältst Du diese Information über

SELECT                              -- Gib mir  
    Articel_ID,                     -- die Artikel-ID  
    COUNT(*) AS anzahl_kommentare   -- und die Anzahl des Auftretens  
FROM                                -- aus der Tabelle  
    Comments                        -- Comments  
GROUP BY                            -- wobei die Anzahl je  
    Articel_ID                      -- Artikel-ID interessiert 

Tabelle - Views:
News_ID | IP_Adresse | Timestamp

Die News_ID entspricht der ID der Haupttabelle - News

Analog erhälst Du die Anzahl der Einträge in Views über

SELECT  
    News_ID,  
    COUNT(*) AS anzahl_views  
FROM  
    Views  
GROUP BY  
    News_ID  

Möchtest Du hier jedoch nur je unterschiedlicher IP-Adresse und News_ID zählen, dann musst Du diese Abfrage entsprechend anpassen. Wäre ja denkbar.

Nun kannst Du das alles einfach zusammenpacken:

SELECT  
    News.*,  
    cc.anzahl_kommentare,  
    cv.anzahl_views  
FROM  
    News  
LEFT JOIN (  
    SELECT  
        Articel_ID,  
        COUNT(*) AS anzahl_kommentare  
    FROM  
        Comments  
    GROUP BY  
        Articel_ID  
) AS cc                                  -- Subselect benötigt zwingend  
                                         -- einen Namen  
ON  
    News.ID = cc.Articel_ID  
LEFT JOIN (  
    SELECT  
        News_ID,  
        COUNT(*) AS anzahl_views  
    FROM  
        Views  
    GROUP BY  
        News_ID  
) AS cv                                   -- das hier auch  
ON  
    News.ID = cv.News_ID  

Unschön ist jetzt noch, dass im Falle fehlender Kommentare oder fehlender Views dort NULL statt 0 steht. Das läßt sich problemlos durch Einsatz der Funktion COALESCE(), das erste von Null verschiedene Argument zurückgibt,  beheben:

SELECT  
    News.*,  
    [link:http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html#function_coalesce@title=COALESCE](cc.anzahl_kommentare, 0) AS kommentare,  
    COALESCE(cv.anzahl_views, 0) AS views  
FROM  
    News  
LEFT JOIN (  
    SELECT  
        Articel_ID,  
        COUNT(*) AS anzahl_kommentare  
    FROM  
        Comments  
    GROUP BY  
        Articel_ID  
) AS cc  
ON  
    News.ID = cc.Articel_ID            -- Join-Bedingung greift auf die  
                                       -- Spalten des Subselects zu, nicht  
                                       -- die der zugrundeliegenden Tabelle!  
LEFT JOIN (  
    SELECT  
        News_ID,  
        COUNT(*) AS anzahl_views  
    FROM  
        Views  
    GROUP BY  
        News_ID  
) AS cv  
ON  
    News.ID = cv.News_ID  

Weil die Aggregatsfunktionen und die Gruppierung in den Subselects erfolgen, muss im äußeren SELECT, das weder eine solche Funktion noch eine Gruppierung aufweist, natürlich auch nicht gruppiert werden.

Freundliche Grüße

Vinzenz