Core: JOIN 3 Tabellen + Count - Problem

  
SELECT a.*,  
  
COUNT( DISTINCT(b.Articel_ID)) AS Comment_Count,  
COUNT( DISTINCT(c.News_ID))  AS View_Count  
                  		             		  
FROM $this->table_name AS a  
LEFT JOIN $this->comment_table as b ON b.Articel_ID = a.ID  
LEFT JOIN $this->view_table as c ON c.News_ID = a.ID  
  
GROUP BY a.ID;  

Hallo Leute,
wie ihr in dem oberen SQL-Statment seht versuche ich drei Tabellen miteinander zu Verknüpfen und jeweils mit den zwei gejointen Tabellen
einen Count auszurechnen,..

Jedoch stimmt der Count-Wert nicht,
habt ihr vielleicht eine Idee wie dieses Statement funktionieren könnte.

Bitte um Antwort!
lG Core

  1. Hallo,

    SELECT a.*,

    COUNT( DISTINCT(b.Articel_ID)) AS Comment_Count,
    COUNT( DISTINCT(c.News_ID))  AS View_Count
                                    
    FROM $this->table_name AS a
    LEFT JOIN $this->comment_table as b ON b.Articel_ID = a.ID
    LEFT JOIN $this->view_table as c ON c.News_ID = a.ID

    GROUP BY a.ID;

      
    
    > wie ihr in dem oberen SQL-Statment seht versuche ich drei Tabellen miteinander zu Verknüpfen und jeweils mit den zwei gejointen Tabellen  
      
    ich habe gedanklich die Variablen ersetzt :-)  
    Dass das Statement keinen Syntaxfehler hervorruft, wird wohl an MySQL liegen.  
      
    
    > einen Count auszurechnen,..  
    > Jedoch stimmt der Count-Wert nicht,  
      
    Das wundert mich bei einem solch fehlerhaften Statement nicht.  
      
    Im Übrigen ist es eine viel bessere Idee, die beteiligten Tabellen auf die relevanten Spalten zu reduzieren, ein paar Beispieldatensätze mitzuliefern und das gewünschte Ergebnis mit der Erläuterung, \*warum\* man dieses Ergebnis haben möchte.  
      
    Die gewünschten Anzahl-Werte solltest Du über Subselects ermitteln.  
      
      
    Freundliche Grüße  
      
    Vinzenz
    
    1. Hallo,
      Das wundert mich bei einem solch fehlerhaften Statement nicht.

      Danke für deine Hilfe,
      die in keinster weise für mich einen konstruktiven Punkt darstellt.
      Das Statement funktioniert nun nach deiner Bearbeiten garnicht mehr.
      D.h.: Ansteller falscher Counter Ergebnisse kommt eine MYSQL Syntax Error.
      Und was daran fehlerhaft ist hast du auch nicht erläutert,..

      Die gewünschten Anzahl-Werte solltest Du über Subselects ermitteln.

      Ein Beispiel wie du dir das vorstellst wäre auch schön gewesen.

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

        Das Statement funktioniert nun nach deiner Bearbeiten garnicht mehr.
        D.h.: Ansteller falscher Counter Ergebnisse kommt eine MYSQL Syntax Error.
        Und was daran fehlerhaft ist hast du auch nicht erläutert,..

        Du wählst (vermutlich) Spalten aus, auf die keine Aggregatsfunktion angewandt wird und nach denen Du nicht gruppierst. Das meckert außer MySQL (im Standardmodus) jedes mir bekannte DBMS an.

        Sprich:
        Wenn Du die GROUP-BY-Klausel verwendest, solltest Du sinnvollerweise auf SELECT * verzichten, weil Du sowieso jede einzelne Spalte in der GROUP-BY-Klausel aufführen musst.

        Die gewünschten Anzahl-Werte solltest Du über Subselects ermitteln.
        Ein Beispiel wie du dir das vorstellst wäre auch schön gewesen.

        Ich habe nicht verstanden, was Du zählen willst. Das geht aus Deinen Ausführungen *nicht* hervor. Ich kenne Deine Tabellen nicht, ich kenne nicht deren Inhalte - und nein, sowas ist *nicht* selbsterklärend.

        Freundliche Grüße

        Vinzenz

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

          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.

          Tabelle - Views:
          News_ID | IP_Adresse | Timestamp

          Die News_ID entspricht der ID der Haupttabelle - News

          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.

          $this->table_name = News;  
          $this->comment_table = "Comments";  
          $this->view_table = "Views";
          
          1. 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

            1. Vielen Vielen Dank,
              ich war echt schon am Verzweifeln!
              Funktioniert perfekt - ich werd es mir noch durchschauen
              bzw. durchgoogeln um es auch zu verstehen ^^

              Zitat:
              COALESCE

              Vielen Dank!

              1. Hallo,

                Funktioniert perfekt - ich werd es mir noch durchschauen
                bzw. durchgoogeln um es auch zu verstehen ^^

                Zitat:
                COALESCE

                wozu googeln, ich hab's doch verlinkt:

                » » 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  
                > > -- [...]  
                
                

                Freundliche Grüße

                Vinzenz