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 >