Vysvětlení
Kořenem problému je nejasná definice „nic“.
NULL
není nic , jen se neví, co to přesně je. "Nic" z hlediska SQL by bylo žádný řádek :nevrací se vůbec nic. To se obvykle stane, když není nalezen žádný řádek. Ale při použití agregačních funkcí , to se nemůže stát, protože podle dokumentace:
avg()
vrátí NULL
když nejsou nalezeny žádné řádky (takže ne "nic"). Získáte řádek s NULL
hodnota jako výsledek – která přepíše vaše init hodnota v kódu, který demonstrujete.
Řešení
Výsledek zabalte do COALESCE
. Ukázka mnohem jednodušší funkce SQL:
CREATE OR REPLACE FUNCTION get_height_sql(firstn varchar, lastn varchar)
RETURNS float AS
$func$
SELECT COALESCE(AVG(((p.h_feet * 12) + p.h_inches) * 2.54)::float, 0)
FROM player p
WHERE p.firstname = firstn
AND p.lastname = lastn
$func$ LANGUAGE sql STABLE;
Totéž lze použít ve funkci plpgsql. Tato funkce může být STABLE
, může pomoci s výkonem v kontextu větších dotazů.
Ostatní případy
Pokud skutečně můžete získat žádný řádek z dotazu jednoduchý COALESCE
by se nezdařilo , protože se nikdy nespustí.
Pro jedinou hodnotu výsledkem můžete celý dotaz zabalit jako:
SELECT COALESCE((SELECT some_float FROM ... WHERE ... LIMIT 1), 0) AS result
PL/pgSQL má schopnost zkontrolovat před skutečným návratem z funkce. Toto funguje pro více řádků s jedním nebo více sloupci , také. Existuje příklad v manuál
demonstrující použití FOUND
:
...
RETURN QUERY SELECT foo, bar ...;
IF NOT FOUND THEN
RETURN QUERY VALUES ('foo_default'::text, 'bar_default'::text);
END IF;
...
Související:
- Vrátit sadu záznamu ( virtuální tabulka) z funkce
- PostgreSQL – Při provádění SELECT zkontrolujte existenci cizího klíče
Chcete-li vždy vrátit přesně jeden řádek , můžete také použít čisté SQL :
SELECT foo, bar FROM tbl
UNION ALL
SELECT 'foo_default', 'bar_default'
LIMIT 1;
Pokud je první SELECT
nevrátí žádný řádek, druhý SELECT
vrátí řádek s výchozími hodnotami.