Wyjaśnienie
Podstawą problemu jest nieostra definicja „nic”.
NULL
to nie nic , po prostu nie wiadomo, co to dokładnie jest. „Nic” w kategoriach SQL oznaczałoby brak wiersza :nic nie jest zwracane. Zwykle dzieje się tak, gdy nie zostanie znaleziony żaden wiersz. Ale podczas korzystania z funkcji agregujących , to nie może się zdarzyć, ponieważ zgodnie z dokumentacją:
avg()
zwraca NULL
gdy nie zostaną znalezione żadne wiersze (a więc nie „nic”). Otrzymasz wiersz z NULL
wartość jako wynik - która zastępuje wartość init w kodzie, który demonstrujesz.
Rozwiązanie
Zawiń wynik w COALESCE
. Demonstracja znacznie prostszej funkcji 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;
To samo może być użyte w funkcji plpgsql. Ta funkcja może być STABLE
, może pomóc w poprawie wydajności w kontekście większych zapytań.
Inne przypadki
Jeśli rzeczywiście możesz pobierz brak wiersza z zapytania, proste COALESCE
nie powiedzie się , ponieważ nigdy nie jest wykonywany.
Dla pojedynczej wartości wynik, możesz po prostu zawinąć całe zapytanie, takie jak:
SELECT COALESCE((SELECT some_float FROM ... WHERE ... LIMIT 1), 0) AS result
PL/pgSQL ma możliwość sprawdzenia przed faktycznym powrotem z funkcji. Działa to w przypadku wielu wierszy z co najmniej jedną kolumną , także. Istnieje przykład w instrukcja
demonstrowanie użycia FOUND
:
...
RETURN QUERY SELECT foo, bar ...;
IF NOT FOUND THEN
RETURN QUERY VALUES ('foo_default'::text, 'bar_default'::text);
END IF;
...
Powiązane:
- Zwróć zestaw rekordów ( wirtualny stół) z funkcji
- PostgreSQL - Sprawdź, czy klucz obcy istnieje podczas wykonywania SELECT
Aby zawsze zwracać dokładnie jeden wiersz , możesz także użyć czystego SQL :
SELECT foo, bar FROM tbl
UNION ALL
SELECT 'foo_default', 'bar_default'
LIMIT 1;
Jeśli pierwszy SELECT
nie zwraca żadnego wiersza, drugi SELECT
zwraca wiersz z wartościami domyślnymi.