Rolf B: Wie die häufigsten Einträge ermitteln. Mehrere bei gleicher Anzahl?

Beitrag lesen

Hallo Klaus1,

Gibt es nicht doch eine Möglichkeit, das direkt in einer Abfrage zu ermitteln?

Doch, natürlich. Aber letztlich führst Du auch dann die Abfrage mehrfach aus. Welches Datenbanksystem verwendest Du genau - incl. Version? Eventuell kann man hier mit CTEs arbeiten (Common Table Expression), um die Query übersichtlicher zu machen.

Mit "klassischem" SQL wird es etwas in dieser Art:

SELECT x.anz, x.name 
FROM   (SELECT   COUNT(name) AS anz, name 
        FROM     tabelle 
        GROUP BY name) x
WHERE  x.anz = (SELECT MAX(y.anzahl) 
                FROM   (SELECT   COUNT(name) AS anzahl
                        FROM     tabelle 
                        GROUP BY name) y) 

Es gibt eine Variante mit ORDER BY - aber die gilt eher als Hack. Im EXPLAIN hat sie bei mir allerdings eine Zeile weniger, d.h. ein Verarbeitungsschritt bei der Ausführung entfällt. Was in der Praxis schneller ist, muss man messen (und es braucht natürlich einen Index auf name, damit der COUNT ohne full table scan erfolgen kann).

SELECT x.anz, x.name 
FROM   (SELECT   COUNT(name) AS anz, name 
        FROM     tabelle
        GROUP BY name) x
WHERE  x.anz = (SELECT   COUNT(NAME) AS anzahl
                FROM     tabelle
                GROUP BY NAME
                ORDER BY anzahl DESC LIMIT 1)

Mit einer CTE sieht es so aus - setzt aber eine neuere Maria oder MYSQL 8 voraus. Und es macht die Arbeit für den Server nicht leichter, es spart Dir nur Schreibarbeit, denke ich. Der Explain wird bei durch die CTE nicht anders.

WITH namecount AS (
  SELECT   COUNT(name) AS anzahl, name 
  FROM     tabelle
  GROUP BY name
)
SELECT anzahl, name 
FROM   namecount 
WHERE  anzahl = (SELECT MAX(anzahl) FROM namecount)

Stell Dir die CTE in diesem Fall als eine Art temporäre View vor.

<exkurs>Richtig spannend werden CTEs erst, wenn sie rekursiv verwendet werden - aber dafür braucht man ein gut geöltes Gehirn, damit die beim Denken verknoteten Nerven sich nachher leichter aufribbeln lassen.</exkurs>

Rolf

--
sumpsi - posui - obstruxi