Explicación
La raíz del problema es la definición confusa de "nada".
NULL
no es nada , simplemente se desconoce qué es exactamente. "Nada" en términos de SQL sería ninguna fila :no se devuelve nada en absoluto. Eso suele suceder cuando no se encuentra ninguna fila. Pero al usar funciones agregadas , eso no puede suceder porque, por documentación:
avg()
devuelve NULL
cuando no se encuentran filas (entonces no "nada"). Obtienes una fila con un NULL
valor como resultado, que sobrescribe su valor inicial en el código que demuestra.
Solución
Envuelva el resultado en COALESCE
. Demostración de una función SQL mucho más simple:
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;
Lo mismo se puede usar en una función plpgsql. Esta función puede ser STABLE
, podría ayudar con el rendimiento en el contexto de consultas más grandes.
Otros casos
Si realmente puedes obtener sin fila de una consulta, un simple COALESCE
fallaría , porque nunca se ejecuta.
Por un valor único resultado, puede envolver toda la consulta como:
SELECT COALESCE((SELECT some_float FROM ... WHERE ... LIMIT 1), 0) AS result
PL/pgSQL tiene la capacidad de verificar antes de regresar de la función. Esto funciona para varias filas con una o más columnas , también. Hay un ejemplo en el manual
demostrando el uso de FOUND
:
...
RETURN QUERY SELECT foo, bar ...;
IF NOT FOUND THEN
RETURN QUERY VALUES ('foo_default'::text, 'bar_default'::text);
END IF;
...
Relacionado:
- Return setof record ( tabla virtual) de la función
- PostgreSQL:compruebe que existe una clave externa al hacer una SELECCIÓN
Para devolver siempre exactamente una fila , también puede usar SQL puro :
SELECT foo, bar FROM tbl
UNION ALL
SELECT 'foo_default', 'bar_default'
LIMIT 1;
Si el primero SELECT
no devuelve ninguna fila, el segundo SELECT
devuelve una fila con valores predeterminados.