Réécriture complète de la question
Je recherche une fonction d'agrégation First ().
Ici, j'ai trouvé quelque chose qui fonctionne presque:
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
);
Le problème est que lorsqu'une colonne varchar (n) passe par la première fonction (), elle est convertie en varchar simple (sans taille). En essayant de renvoyer la requête dans une fonction en tant qu'élément RETURNS SETOF, j'obtiens l'erreur suivante:
ERREUR: la structure de la requête ne correspond pas au type de résultat de la fonction ) ligne 31 à RETURN QUERY
Dans la même page wiki, il y a un lien vers une version C de la fonction qui remplacerait ce qui précède. Je ne sais pas comment l'installer, mais je me demande si cette version pourrait résoudre mon problème.
Pendant ce temps, existe-t-il un moyen de modifier la fonction ci-dessus afin qu'elle renvoie exactement le même type de la colonne d'entrée?
la source
DISTINCT ON
cela ne fonctionnera pas dans ce cas. Ce n'est pas une fonction d'agrégation, vous filtrez réellement les données et vous ne pouvez donc le faire qu'une seule fois.Oui, j'ai découvert un moyen simple avec votre cas en utilisant certaines fonctionnalités de PostgreSQL 9.4+
Voyons cet exemple:
J'espère que cela vous aidera dans votre cas.
la source
DOMAIN
les types de données ou d'autres petites exceptions. Il est également beaucoup plus complexe et prend du temps, constituant un tableau de l'ensemble des données. La solution simple serait de créer un agrégat personnalisé, mais jusqu'à présent, je n'ai pas trouvé la solution idéale même avec cela. Les fonctions de fenêtre sont également mauvaises, car elles ne peuvent pas être utilisées de la même manière que vous pourriez utiliser des agrégats (avec des instructions FILTER ou dans CROSS JOIN LATERAL)Pas une réponse directe à votre question, mais vous devriez essayer la
first_value
fonction fenêtre. Cela fonctionne comme ceci:);
Ensuite, si vous voulez le premier élément de chaque
cat
(catégorie), vous interrogerez comme ça:ou:
la source
select distinct x, first_value(y) over (partition by x), first_value(z) over (partition by x) from ...
. Probablement inefficace mais suffisant pour que je puisse continuer le prototypage. Certainement quelque chose à revisiter cependant!