MAESTRO!

Guillermo Villanueva



El 3 de septiembre de 2014, 19:46, Alvaro Herrera <alvhe...@2ndquadrant.com>
escribió:

> Guillermo E. Villanueva escribió:
> > Hola amigos, con una tabla mas o menos como:
> > id  t
> > ---+---
> > 1   0.3
> > 1   0.5
> > 2   1.1
> > 2   1.2
> > 2   1.1
> > 3   0.5
> > 3   0.6
> > Existe alguna forma de función de ventana que me permita obtener la
> > cantidad de ids diferentes listadas? En este caso e (tres)
> > id  t   cant
> > ---+---+----
> > 1   0.3    3
> > 1   0.5    3
> > 2   1.1    3
> > 2   1.2    3
> > 2   1.1    3
> > 3   0.5    3
> > 3   0.6    3
>
> ¡Es muy simple!  Simplemente forma un array con los id que son
> "distinct", luego cuentas el largo de este array sobre la ventana del
> resultado completo:
>
> =# SELECT id, t, array_length(array_agg(DISTINCT id) OVER (), 1) from gv;
>
> ERROR:  DISTINCT no está implementado para funciones de ventana deslizante
>
> Oh :-(
>
> Para corregir esto puedes crear una función de agregación propia, que
> agregue elementos sólo cuando son únicos:
>
> create or replace function array_agg_unique(anyarray, anyelement) returns
> anyarray
>    language sql
>    as $$ select array_agg(distinct a)
>           from unnest(coalesce($1, '{}') || $2) a;
>       $$;
> create aggregate array_agg_uniq(anyelement) (
>     sfunc = array_agg_unique,
>     stype = anyarray,
>     initcond = '{}'
> );
>
> Este sí funciona:
>
> =# select id, t, array_length(array_agg_uniq(id) over (), 1) from gv;
>  id |  t  | array_length
> ----+-----+--------------
>   1 | 0.3 |            3
>   1 | 0.5 |            3
>   2 | 1.1 |            3
>   2 | 1.2 |            3
>   2 | 1.1 |            3
>   3 | 0.5 |            3
>   3 | 0.6 |            3
> (7 filas)
>
> Ignoro cómo será el rendimiento.
>
> --
> Álvaro Herrera                http://www.2ndQuadrant.com/
> PostgreSQL Development, 24x7 Support, Training & Services
>

Responder a