Hay más en esta pregunta de lo que parece.
Versión sencilla
Esto es mucho más rápido y sencillo:
SELECT property_name
,(count(value_a = value_b OR NULL) * 100) / count(*) AS pct
FROM my_obj
GROUP BY 1;
Resultado:
property_name | pct
--------------+----
prop_1 | 17
prop_2 | 43
¿Cómo?
-
No necesitas una función para esto en absoluto.
-
En lugar de contar
value_b
(que no necesita para empezar) y calculando el total, usecount(*)
para el total. Más rápido, más simple. -
Esto supone que no tiene
NULL
valores. Es decir. ambas columnas están definidasNOT NULL
. Falta información en su pregunta.
Si no es así, su consulta original probablemente no está haciendo lo que cree que hace . Si alguno de los valores es NULL, su versión no cuenta esa fila en absoluto. Incluso podría provocar una división por cero excepción de esta manera.
Esta versión también funciona con NULL.count(*)
produce el recuento de todas las filas, independientemente de los valores. -
Así es como funciona el conteo:
TRUE OR NULL = TRUE FALSE OR NULL = NULL
count()
ignora los valores NULL. Voilá. -
La precedencia de operadores gobierna que
=
se une antes deOR
. Puede agregar paréntesis para que quede más claro:count ((value_a = value_b) OR FALSE)
-
Puedes hacer lo mismo con
count NULLIF(<expression>, FALSE)
-
El tipo de resultado de
count()
esbigint
por defecto.
Una divisiónbigint / bigint
, trunca dígitos fraccionarios .
Incluye dígitos fraccionarios
Usa 100.0
(con dígito fraccionario) para forzar que el cálculo sea numeric
y por lo tanto preservar los dígitos fraccionarios.
Es posible que desee utilizar round()
con esto:
SELECT property_name
,round((count(value_a = value_b OR NULL) * 100.0) / count(*), 2) AS pct
FROM my_obj
GROUP BY 1;
Resultado:
property_name | pct
--------------+-------
prop_1 | 17.23
prop_2 | 43.09
Aparte:
Uso value_a
en lugar de valueA
. No utilice identificadores de mayúsculas y minúsculas sin comillas en PostgreSQL. He visto demasiadas preguntas desesperadas provenientes de esta locura. Si se pregunta de qué estoy hablando, lea el capítulo Identificadores y palabras clave del manual.