fanatiker: MySQL: Zählt es falsch?

Hallo,

meine Datenbank stellt den Hintergrund einer (noch im Aufbau befindlichen) Bilder-Galerie dar.
Der Aufbau ist logisch:
Kategorien > Unterkategorien > Alben > Bilder.

Kategorien und Unterkategorien sind in der Tabelle gal_cats. Alben in der Tabelle gal_albums. Bilder in der Tabelle gal_pics.

Für die Übersicht auf der Startseite soll der Name der Kategorie, nebst der Anzahl der sich darin befindlichen Alben und die Anzahl der Bilder (rekursiv) stehen.

Für mein Beispiel sehen die Tabellen momentan wie folgt aus:

Der entsprechende SQL sieht so aus:

  
SELECT c.ID, c.name, count(a.ID) ac, count(p.ID) pc  
FROM  
(gal_cats c LEFT JOIN gal_albums a ON c.ID=a.cat_id)  
  LEFT JOIN gal_pics p ON a.ID=p.album_id  
GROUP BY c.ID  

(ac steht für album-count, und pc für picture-count)

Das Ergebnis wäre Folgendes:

Die "4" im Feld "ac" stimmt hier nicht. Ich jedenfalls zähle nur drei Alben in der Kategorie 2. Ich vermute, MySQL zählt hier etwas mit, was man nicht sieht/erkennt.

Welcher Denkfehler ist mir hier unterlaufen?

Gruß
Fanatiker

  1. Du kriegst für den obersten Eintrag in gal_albums (mit ID 1) zwei Zeilen aus gal_pics zurück.

    1. Hallo Encoder,

      Du kriegst für den obersten Eintrag in gal_albums (mit ID 1) zwei Zeilen aus gal_pics zurück.

      Oh ja, jetzt sehe ich es auch.
      Funktioniert mein Wunsch dann überhaupt so wie ich es mir vorstelle? Habe es auch schon mit Subselects versucht, doch damit komme ich auch nicht weiter.
      Wie müsste der SQL lauten, damit er tatsächlich nur die Alben und allen derer Bilder zählt?

      Gruß
      fanatiker

      1. Habe es auch schon mit Subselects versucht, doch damit komme ich auch nicht weiter.

        Spätestens das sollte doch funktionieren. Wie man in mysql mit COUNT irgendwas bestimmtes zählen kann weiß ich nicht. Aber sowas hier müsste doch tun:

        SELECT c.id, count(*) as anzahlAlben, sum(anzahlBilder)
        FROM c LEFT JOIN a ON ...
         LEFT JOIN (SELECT a.id, count(*) as anzahlBilder FROM a LEFT JOIN p ... GROUP BY a.id) sub ON sub.id = a.id
        GROUP BY c.id

        jedenfalls so ähnlich.
        WHERE Klauseln müsstest du dann halt in beide Abfragen einbauen.

        1. Hallo,

          jedenfalls so ähnlich.

          Mit viel gefrickel habe ich einen funktionierenden SQL bekommen:

            
          SELECT  
          	c.id, c.name,  
          	count(a.ID) ac,  
          	sum(anzahlBilder) pc  
          FROM gal_cats c  
          LEFT JOIN gal_albums a ON c.ID=a.cat_id  
          	LEFT JOIN (SELECT a2.id, count(a2.ID) as anzahlBilder  
          			FROM gal_albums a2  
          			INNER JOIN gal_pics p ON p.album_id=a2.ID  
          			GROUP BY a2.id) sub  
          	ON sub.id = a.id  
          GROUP BY c.id  
          
          

          Wichtig ist das INNER JOIN im sub. Ansonsten bekommt man für jede Kategorie "1" Bild, obwohl keins existiert.

          Wenn jemand noch Anmerkungen/Verbesserungsvorschläge hat - ich bin offen für alles.

          Vielen Dank Encoder!
          fanatiker

        2. moin!

          Wie man in mysql mit COUNT irgendwas bestimmtes zählen kann weiß ich nicht.

          hab das hier nur überflogen. Weiß nicht ob es hier das richtige ist, aber mysql kennt count_distinct oder distinct_count o.ä. Bei Transact-SQL hat count() einen Parameter distinct. count(distinct ID)

          und jetzt ab zur arbeit.

          --
          Vergesst Chuck Norris.
          Sponge Bob kann unter Wasser grillen!