Geralmente você precisa estudar o básico , antes de começar a fazer perguntas.
Leia o excelente manual sobre
CREATE FUNCTION
, PL/pgSQL
e funções SQL
. Principais pontos porque o exemplo é absurdo
-
Primeiro, você não pode entregar um identificador como você faz. Os identificadores não podem ser parametrizados em SQL simples. Você precisaria de SQL dinâmico para isso.
Na verdade, você não precisa disso, de acordo com suas necessidades. Há apenas uma mesa envolvida. É um absurdo tentar parametrizá-lo.
-
Não use nomes de tipo como identificadores. Eu uso_date
em vez dedate
como nome do parâmetro e renomeou sua coluna de tabela paraasset_date
.ALTER
sua definição de tabela de acordo.
-
Uma função que busca dados de uma tabela nunca pode serIMMUTABLE
. Leia o manual.
-
Você está misturando a sintaxe SQL com elementos plpgsql de maneiras sem sentido.WITH
faz parte de umSELECT
instrução e não pode ser misturado com estruturas de controle plpgsql comoLOOP
ouIF
.
Função adequada
Uma função adequada pode ser assim (uma de muitas maneiras):
CREATE FUNCTION percentage_change_func(_asset_symbol text)
RETURNS TABLE(asset_date date, price numeric, pct_change numeric) AS
$func$
DECLARE
last_price numeric;
BEGIN
FOR asset_date, price IN
SELECT a.asset_date, a.price
FROM asset_histories a
WHERE a.asset_symbol = _asset_symbol
ORDER BY a.asset_date -- traverse ascending
LOOP
pct_change := price / last_price; -- NULL if last_price is NULL
RETURN NEXT;
last_price := price;
END LOOP;
END
$func$ LANGUAGE plpgsql STABLE
O desempenho não deveria ser tão ruim, mas é apenas uma complicação inútil.
Solução adequada:consulta simples
A maneira mais simples (e provavelmente mais rápida) seria com a função window
lag()
:SELECT asset_date, price
,price / lag(price) OVER (ORDER BY asset_date) AS pct_change
FROM asset_histories
WHERE asset_symbol = _asset_symbol
ORDER BY asset_date;
Desvio padrão
De acordo com seu comentário posterior, você deseja calcular números estatísticos como desvio padrão.
Há funções de agregação para estatísticas no PostgreSQL.