Ludwig II: verschiedene Kategorien in einer SELECT Abfrage zählen (addieren)

Hallo, ich fange gerade an mich mit mysql zu beschäftigen.

Jetzt habe ich zwei Tabellen angelegt, ein davon hat die Kategorien und in der anderen sind meine Daten.

Jetzt würde ich gerne eine Abfrage starten und alle meine Daten zählen in Bezug auf die Kategorie.

Id Titel kat

1.inhalt.1

2.inhalt.1

3.inhalt.1

4.inhalt.2

5.inhalt.2

6.inhalt.2

Ich kann zwar alle Datensätze zählen und mit WHERE die einzelnen Kategorien filtern, aber dann müsste ich ja 3-mal ein Zählvorgang starten und wenn es eine weitere Kategorie gibt, noch einen.

SELECT count(*) AS total FROM tab_inhalt

Kann man nicht mit einer einzigen Abfrage alle Kategorien zählen

  1. Hallo Ludwig,

    Kann man nicht mit einer einzigen Abfrage alle Kategorien zählen

    Doch, das kann man, mit der GROUP BY Klausel.

    Rolf

    --
    sumpsi - posui - obstruxi
  2. Lieber Ludwig,

    Du willst im Ergebnis doch das stehen haben:

    kat:1, total:3
    kat:2, total:3

    SELECT
     `kategorientabelle`.`kat` AS `kat`,
     count(
      SELECT *
      FROM `titeltabelle`
      WHERE `kategorientabelle`.`kat` = `titeltabelle`.`kat`
     ) AS `total`
    FROM `kategorientabelle`
    

    Das ist jetzt ungetestet, zeigt aber, wohin die Reise gehen könnte.

    Liebe Grüße

    Felix Riesterer

    1. Hallo Felix,

      okay - das hatte ich nicht bedacht. Was ist, wenn in der Kategorientabelle eine Kategorie steht, die in der Datentabelle keine Einträge hat.

      Das ist jetzt der alte Streit Subselect vs Join, den ich gerne schüren möchte 😉. Deine Query führt einen COUNT pro Kategorie durch, d.h. bei 100 Kategorien 100 COUNTs.

      Man müsste es im real live mit großen Tabellen messen, aber eigentlich sollte für solche Aufgaben der LEFT JOIN optimiert sein. Ich gehe jetzt von einem Modell aus, wo Kategorien- und Datentabelle eine id-Spalte haben und in den Daten die kat_id als Fremdschlüssel steht.

      Für die Gruppierung reicht eigentlich die id-Spalte der Kategorien-Tabelle aus. Aber formal muss eine nicht aggregierte Spalte, die im SELECT auszugeben ist, im Group By gelistet sein. Und wer weiß, ob der Name eindeutig ist...

      SELECT kategorien.id as KatId,
             kategorien.name as Kategorie,
             COUNT(daten.id) as Anzahl
      FROM kategorien LEFT JOIN daten
                      ON kategorien.id = daten.kat_id
      GROUP BY kategorien.id, kategorien.kat
      

      Der Left Join erzeugt für Kategorien, die keine Daten haben, NULL-Werte für die Spalten der Datentabelle. Und COUNT(feldname) zählt Rows, wo das angegebene Feld null ist, nicht mit. Da die id der Daten in der DB sicherlich nie null ist, kann man auf diese Weise für unbelegte Kategorien eine 0 bekommen.

      Beide Queries, mit Subselect oder mit Left Join, setzen voraus dass die Datentabelle einen Index hat, in dem die Kategorie-ID die erste Spalte ist. Andernfalls wird es bei größeren Datenmengen sehr langsam.

      Rolf

      --
      sumpsi - posui - obstruxi