Il y a plus à cette question qu'il n'y paraît.
Version simplifiée
C'est beaucoup plus rapide et plus simple :
SELECT property_name
,(count(value_a = value_b OR NULL) * 100) / count(*) AS pct
FROM my_obj
GROUP BY 1;
Résultat :
property_name | pct
--------------+----
prop_1 | 17
prop_2 | 43
Comment ?
-
Vous n'avez pas du tout besoin d'une fonction pour cela.
-
Au lieu de compter
value_b
(dont vous n'avez pas besoin pour commencer) et en calculant le total, utilisezcount(*)
pour la totalité. Plus rapide, plus simple. -
Cela suppose que vous n'avez pas
NULL
valeurs. C'est à dire. les deux colonnes sont définiesNOT NULL
. Les informations manquent dans votre question.
Si ce n'est pas le cas, votre requête d'origine ne fait probablement pas ce que vous pensez qu'elle fait . Si l'une des valeurs est NULL, votre version ne compte pas du tout cette ligne. Vous pourriez même provoquer une division par zéro exception de cette façon.
Cette version fonctionne également avec NULL.count(*)
produit le nombre de toutes les lignes, quelles que soient les valeurs. -
Voici comment fonctionne le décompte :
TRUE OR NULL = TRUE FALSE OR NULL = NULL
count()
ignore les valeurs NULL. Voilà. -
La priorité des opérateurs régit que
=
se lie avantOR
. Vous pouvez ajouter des parenthèses pour le rendre plus clair :count ((value_a = value_b) OR FALSE)
-
Vous pouvez faire la même chose avec
count NULLIF(<expression>, FALSE)
-
Le type de résultat de
count()
estbigint
par défaut.
Une divisionbigint / bigint
, tronque les chiffres fractionnaires .
Inclure les chiffres fractionnaires
Utilisez 100.0
(avec chiffre fractionnaire) pour forcer le calcul à être numeric
et ainsi préserver les chiffres fractionnaires.
Vous pouvez utiliser round()
avec ceci :
SELECT property_name
,round((count(value_a = value_b OR NULL) * 100.0) / count(*), 2) AS pct
FROM my_obj
GROUP BY 1;
Résultat :
property_name | pct
--------------+-------
prop_1 | 17.23
prop_2 | 43.09
En aparté :
J'utilise value_a
au lieu de valueA
. N'utilisez pas d'identificateurs à casse mixte sans guillemets dans PostgreSQL. J'ai vu trop de questions désespérées venant de cette folie. Si vous vous demandez de quoi je parle, lisez le chapitre Identifiants et mots clés du manuel.