SQL: COUNT inusuali

In questo articolo illustrerò alcuni modi di usare la funzione COUNT().

La funzione COUNT() viene usata per contare (appunto) quanti record ci sono in una tabella o vista, eventualmente rispondenti ad una determinata condizione.

Ad esempio potremmo voler contare quanti clienti hanno sede a Milano.

SELECT
    COUNT(*) AS qClienti
FROM
    Clienti
WHERE
   Localita='MILANO'

Potrebbe succedere però di dover riportare più conteggi; ad esempio quanti clienti hanno sede a Milano e quanti in Lombardia.

La prima soluzione che viene in mente è di eseguire due interrogazioni, con due WHERE diverse; si potrebbero anche riunire le due interrogazioni con una UNION, in questo modo:

SELECT SUM(cMilano) AS qMilano, SUM(cLombardia) AS qLombardia FROM
   (SELECT COUNT(*) AS cMilano, 0 as cLombardia FROM Clienti WHERE Localita='MILANO'
    UNION
    SELECT 0 AS cMilano, COUNT(*) AS cLombardia FROM Clienti WHERE Regione='LOMBARDIA')

Non il massimo dell’eleganza, né dell’efficienza.

Nella funzione COUNT possiamo però usare l’istruzione CASE, che ci permetterà di scrivere una interrogazione migliore.

Sfrutteremo la regola per cui i NULL non vengono contati nella COUNT; in particolare, nel nostro caso, se il risultato della WHEN è positivo (cioè corrisponde) viene restituito un risultato non-NULL, e conseguentemente contato; altrimenti (un altrimenti implicito) viene riportato NULL, che non viene contato.

SELECT
   (COUNT(CASE WHEN Localita='MILANO' THEN 1 END)) qMilano,
   (COUNT(CASE WHEN Regione='LOMBARDIA' THEN 1 END)) qLombardia
FROM
   CLIENTI

La query è più pulita, più performante e più manutenibile. Non lasciatevi fuorviare dalla cifra ‘1’ restituita dal CASE; un qualunque valore non-NULL va altrettanto bene (es.: COUNT(CASE WHEN Localita=’MILANO’ THEN ‘Ok!’ END)  )

Tutte le funzioni di aggregazione (COUNT, SUM, AVG, ecc.) possono essere usate in questo modo.

Replica