C'è di più in questa domanda di quanto possa sembrare.
Versione semplice
Questo è molto più veloce e più semplice:
SELECT property_name
,(count(value_a = value_b OR NULL) * 100) / count(*) AS pct
FROM my_obj
GROUP BY 1;
Risultato:
property_name | pct
--------------+----
prop_1 | 17
prop_2 | 43
Come?
-
Non hai affatto bisogno di una funzione per questo.
-
Invece di contare
value_b(con cui non è necessario iniziare) e calcolando il totale, usacount(*)per il totale. Più veloce, più semplice. -
Ciò presuppone che tu non abbia
NULLvalori. Cioè. entrambe le colonne sono definiteNOT NULL. Le informazioni mancano nella tua domanda.
In caso negativo, la tua query originale probabilmente non sta facendo ciò che pensi . Se uno qualsiasi dei valori è NULL, la tua versione non conta affatto quella riga. Potresti anche provocare una divisione per zero eccezione in questo modo.
Questa versione funziona anche con NULL.count(*)produce il conteggio di tutte le righe, indipendentemente dai valori. -
Ecco come funziona il conteggio:
TRUE OR NULL = TRUE FALSE OR NULL = NULLcount()ignora i valori NULL. Voilà. -
La precedenza dell'operatore regola quel
=si lega prima diOR. Potresti aggiungere parentesi per renderlo più chiaro:count ((value_a = value_b) OR FALSE) -
Puoi fare lo stesso con
count NULLIF(<expression>, FALSE) -
Il tipo di risultato di
count()èbigintper impostazione predefinita.
Una divisionebigint / bigint, tronca le cifre frazionarie .
Includi cifre frazionarie
Usa 100.0 (con cifra frazionaria) per forzare il calcolo a essere numeric e quindi preservare le cifre frazionarie.
Puoi utilizzare round() con questo:
SELECT property_name
,round((count(value_a = value_b OR NULL) * 100.0) / count(*), 2) AS pct
FROM my_obj
GROUP BY 1;
Risultato:
property_name | pct
--------------+-------
prop_1 | 17.23
prop_2 | 43.09
Per inciso:
io uso value_a invece di valueA . Non utilizzare identificatori di maiuscole e minuscole non quotate in PostgreSQL. Ho visto troppe domande disperate provenire da questa follia. Se ti chiedi di cosa sto parlando, leggi il capitolo Identificatori e parole chiave del manuale.