Reescrita da pergunta completa
Estou procurando uma função agregada First ().
Aqui encontrei algo que quase funciona:
CREATE OR REPLACE FUNCTION public.first_agg ( anyelement, anyelement )
RETURNS anyelement LANGUAGE sql IMMUTABLE STRICT AS $$
SELECT $1;
$$;
-- And then wrap an aggregate around it
CREATE AGGREGATE public.first (
sfunc = public.first_agg,
basetype = anyelement,
stype = anyelement
);
O problema é que, quando uma coluna varchar (n) passa pela primeira função (), é convertida em varchar simples (sem tamanho). Tentando retornar a consulta em uma função como RETURNS SETOF anyelement, recebo o seguinte erro:
ERRO: a estrutura da consulta não corresponde ao tipo de resultado da função Estado: SQL: 42804 Detalhe: Variação de caracteres do tipo retornado não corresponde à variação de caracteres do tipo esperado (40) na coluna 2. Contexto: Função PL / pgSQL vsr_table_at_time (anyelement, timestamp sem fuso horário ) linha 31 em RETURN QUERY
Na mesma página wiki, há um link para uma versão C da função que substituiria a acima. Não sei como instalá-lo, mas me pergunto se esta versão poderia resolver meu problema.
Enquanto isso, existe uma maneira de alterar a função acima para que ela retorne exatamente o mesmo tipo da coluna de entrada?
fonte
DISTINCT ON
não funcionará neste caso. Não é uma função agregada; na verdade, você está filtrando os dados e pode fazê-lo apenas uma vez.Sim, eu descobri uma maneira fácil com o seu caso, usando alguns recursos do PostgreSQL 9.4+
Vamos ver este exemplo:
Espero que ajude você no seu caso.
fonte
DOMAIN
tipos de dados ou outras pequenas exceções. Também é muito mais complexo e demorado, construindo uma matriz de todo o conjunto de dados. A solução simples seria criar um agregado personalizado, mas até agora ainda não encontrei a solução ideal. Funções da janela também são ruins, uma vez que não pode ser usado da mesma forma que você poderia usar agregados (com instruções de filtro, ou em CROSS JOIN LATERAL)Não é uma resposta direta à sua pergunta, mas você deve tentar a
first_value
função da janela. Funciona assim:);
Então, se você quiser o primeiro item em cada
cat
(categoria), consultará assim:ou:
fonte
select distinct x, first_value(y) over (partition by x), first_value(z) over (partition by x) from ...
. Provavelmente ineficiente, mas suficiente para eu continuar com a prototipagem. Definitivamente algo para revisitar embora!