Der er mere i dette spørgsmål, end det ser ud til.
Simpel version
Det er meget hurtigere og enklere:
SELECT property_name
,(count(value_a = value_b OR NULL) * 100) / count(*) AS pct
FROM my_obj
GROUP BY 1;
Resultat:
property_name | pct
--------------+----
prop_1 | 17
prop_2 | 43
Hvordan?
-
Du behøver slet ikke en funktion til dette.
-
I stedet for at tælle
value_b
(som du ikke behøver til at begynde med) og beregne totalen, brugcount(*)
for det samlede beløb. Hurtigere, enklere. -
Dette forudsætter, at du ikke har
NULL
værdier. dvs. begge kolonner er defineretNOT NULL
. Oplysningerne mangler i dit spørgsmål.
Hvis ikke, gør din oprindelige forespørgsel sandsynligvis ikke, hvad du tror, den gør . Hvis nogen af værdierne er NULL, tæller din version slet ikke denne række. Du kan endda fremprovokere en deling-for-nul undtagelse på denne måde.
Denne version fungerer også med NULL.count(*)
producerer antallet af alle rækker, uanset værdier. -
Sådan fungerer optællingen:
TRUE OR NULL = TRUE FALSE OR NULL = NULL
count()
ignorerer NULL-værdier. Voilá. -
Operatørprioritet styrer denne
=
binder førOR
. Du kan tilføje parenteser for at gøre det klarere:count ((value_a = value_b) OR FALSE)
-
Du kan gøre det samme med
count NULLIF(<expression>, FALSE)
-
Resultattypen
count()
erbigint
som standard.
En divisionbigint / bigint
, afkorter brøkcifre .
Medtag brøktal
Brug 100.0
(med brøktal) for at tvinge beregningen til at være numeric
og derved bevare brøktal.
Du vil måske bruge round()
med denne:
SELECT property_name
,round((count(value_a = value_b OR NULL) * 100.0) / count(*), 2) AS pct
FROM my_obj
GROUP BY 1;
Resultat:
property_name | pct
--------------+-------
prop_1 | 17.23
prop_2 | 43.09
Som en sidebemærkning:
Jeg bruger value_a
i stedet for valueA
. Brug ikke uciterede identifikatorer med blandede store og små bogstaver i PostgreSQL. Jeg har set for mange desperate spørgsmål komme fra denne dårskab. Hvis du undrer dig over, hvad jeg taler om, så læs kapitlet Identifikatorer og nøgleord i manualen.