Explicação
A raiz do problema é a definição difusa de "nada".
NULL
não é nada , é apenas desconhecido o que é exatamente. "Nada" em termos de SQL seria nenhuma linha :nada é retornado. Isso normalmente acontece quando nenhuma linha é encontrada. Mas ao usar funções agregadas , isso não pode acontecer porque, por documentação:
avg()
retorna NULL
quando nenhuma linha for encontrada (portanto, não "nada"). Você obtém uma linha com um NULL
valor como resultado - que substitui seu valor de inicialização no código que você demonstra. Solução
Envolva o resultado em
COALESCE
. Demonstrando uma função SQL muito mais simples: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;
SQL Fiddle.
O mesmo pode ser usado em uma função plpgsql. Esta função pode ser
STABLE
, pode ajudar no desempenho no contexto de consultas maiores. Outros casos
Se você realmente pode obter nenhuma linha de uma consulta, um simples
COALESCE
faria , porque nunca é executado. Por um valor único resultado, você pode simplesmente envolver toda a consulta como:
SELECT COALESCE((SELECT some_float FROM ... WHERE ... LIMIT 1), 0) AS result
O PL/pgSQL tem a capacidade de verificar antes de retornar da função. Isso funciona para várias linhas com uma ou mais colunas , também. Há um exemplo em o manual demonstrando o uso de
FOUND
:...
RETURN QUERY SELECT foo, bar ...;
IF NOT FOUND THEN
RETURN QUERY VALUES ('foo_default'::text, 'bar_default'::text);
END IF;
...
Relacionado:
- Retornar conjunto de registro ( tabela virtual) da função
- PostgreSQL - Verifica se existe chave estrangeira ao fazer um SELECT
Para sempre retornar exatamente uma linha , você também pode usar SQL puro :
SELECT foo, bar FROM tbl
UNION ALL
SELECT 'foo_default', 'bar_default'
LIMIT 1;
Se o primeiro
SELECT
não retorna nenhuma linha, o segundo SELECT
retorna uma linha com padrões.