V této otázce je více, než by se mohlo zdát.
Jednoduchá verze
To je mnoho rychlejší a jednodušší:
SELECT property_name
,(count(value_a = value_b OR NULL) * 100) / count(*) AS pct
FROM my_obj
GROUP BY 1;
Výsledek:
property_name | pct
--------------+----
prop_1 | 17
prop_2 | 43
Jak?
-
Na to vůbec nepotřebujete žádnou funkci.
-
Místo počítání
value_b
(se kterým nemusíte začínat) a pro výpočet součtu použijtecount(*)
za celkovou částku. Rychlejší, jednodušší. -
To předpokládá, že nemáte
NULL
hodnoty. Tj. oba sloupce jsou definoványNOT NULL
. Informace ve vaší otázce chybí.
Pokud ne, váš původní dotaz pravděpodobně nedělá to, co si myslíte, že dělá . Pokud je některá z hodnot NULL, vaše verze tento řádek vůbec nepočítá. Můžete dokonce vyprovokovat dělení nulou výjimka tímto způsobem.
Tato verze funguje také s NULL.count(*)
vytvoří počet všech řádků bez ohledu na hodnoty. -
Počítání funguje následovně:
TRUE OR NULL = TRUE FALSE OR NULL = NULL
count()
ignoruje hodnoty NULL. Voilá. -
Přednost operátora určuje
=
se váže předOR
. Můžete přidat závorky, aby to bylo jasnější:count ((value_a = value_b) OR FALSE)
-
Totéž můžete provést pomocí
count NULLIF(<expression>, FALSE)
-
Typ výsledku
count()
jebigint
ve výchozím nastavení.
Děleníbigint / bigint
, zkrátí desetinná místa .
Zahrňte zlomkové číslice
Použijte 100.0
(s desetinnou číslicí), aby byl výpočet numeric
a tím zachovat zlomkové číslice.
Možná budete chtít použít round()
s tímto:
SELECT property_name
,round((count(value_a = value_b OR NULL) * 100.0) / count(*), 2) AS pct
FROM my_obj
GROUP BY 1;
Výsledek:
property_name | pct
--------------+-------
prop_1 | 17.23
prop_2 | 43.09
Kromě toho:
Používám value_a
místo valueA
. V PostgreSQL nepoužívejte identifikátory se smíšenou velikostí písmen v uvozovkách. Viděl jsem příliš mnoho zoufalých otázek vycházejících z této pošetilosti. Pokud vás zajímá, o čem mluvím, přečtěte si kapitolu Identifikátory a klíčová slova v příručce.