Pregunta completa reescritura
Estoy buscando una función agregada First ().
Aquí encontré algo que casi 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
);
El problema es que cuando una columna varchar (n) pasa a través de la primera función (), se convierte en varchar simple (sin tamaño). Intentando devolver la consulta en una función como DEVOLUCIÓN DE CONFIGURACIÓN, obtengo el siguiente error:
ERROR: la estructura de la consulta no coincide con el tipo de resultado de la función Estado de SQL: 42804 Detalles: La variación del carácter de tipo devuelto no coincide con el tipo de variación esperado (40) en la columna 2. Contexto: función PL / pgSQL vsr_table_at_time (anyelement, marca de tiempo sin zona horaria ) línea 31 en CONSULTA DEVUELTA
En la misma página wiki hay un enlace a una versión C de la función que reemplazaría lo anterior. No sé cómo instalarlo, pero me pregunto si esta versión podría resolver mi problema.
Mientras tanto, ¿hay alguna manera de que pueda cambiar la función anterior para que devuelva exactamente el mismo tipo de la columna de entrada?
fuente
DISTINCT ON
no funcionará en este caso. No es una función agregada, en realidad está filtrando los datos, por lo que solo puede hacerlo una vez.Sí, descubrí una manera fácil con su caso mediante el uso de algunas características en PostgreSQL 9.4+
Veamos este ejemplo:
Espero que te ayude en tu caso.
fuente
DOMAIN
tipos de datos u otras pequeñas excepciones. También es mucho más complejo y requiere mucho tiempo, ya que crea una matriz de todo el conjunto de datos. La solución simple sería crear un agregado personalizado, pero hasta ahora no he encontrado la solución ideal incluso con eso. Las funciones de ventana también son malas, ya que no se pueden usar de la misma manera que se podrían usar agregados (con declaraciones FILTER o en CROSS JOIN LATERAL)No es una respuesta directa a su pregunta, pero debe probar la
first_value
función de ventana. Funciona así:);
Luego, si desea el primer elemento en cada
cat
(categoría), consultará así:o:
fuente
select distinct x, first_value(y) over (partition by x), first_value(z) over (partition by x) from ...
. Probablemente ineficiente pero suficiente para que yo pueda seguir con la creación de prototipos. ¡Definitivamente algo para volver a visitar!