Funcion de Agregacion

Lists: pgsql-es-ayuda
From: victor benitez <vbenitez(at)galilea(dot)cl>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Funcion de Agregacion
Date: 2006-05-02 16:22:55
Message-ID: 4457875F.9090407@galilea.cl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

Estimados Listeros:

Quisiera saber si alguien sabe como hacer una funcion de agregacion
para calcular la moda (El valor mas repetido de una muestra).

logre hacer algo con una tabla temporal, en la cual guardo el valor
y la cantidad de veces que se repite, y de esto saco el que mas se
repite, pero no es lo mas optimo.

Saludos.

Victor Benitez
Galilea S.A.

--
Este mensaje ha sido analizado por nuestros servidores
en busca de virus y otros contenidos peligrosos,
y se considera que está limpio.

Attachment Content-Type Size
vbenitez.vcf text/x-vcard 86 bytes

From: Juan Martínez <jeugenio(at)umcervantes(dot)cl>
To: victor benitez <vbenitez(at)galilea(dot)cl>
Cc: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Funcion de Agregacion
Date: 2006-05-02 16:46:41
Message-ID: 1146588402.7355.10.camel@localhost.localdomain
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

El mar, 02-05-2006 a las 12:22 -0400, victor benitez escribió:
> Estimados Listeros:
>
> Quisiera saber si alguien sabe como hacer una funcion de agregacion
> para calcular la moda (El valor mas repetido de una muestra).

Mmm...algo asi puede servir:

SELECT max(subtotal)
FROM (SELECT descripcion_valor,count(valor) as subtotal
FROM tabla
GROUP BY descripcion_valor) AS tabla_1;

--
Juan Martínez
Depto. Inf.
UMC


From: victor benitez <vbenitez(at)galilea(dot)cl>
To: Juan Martínez <jeugenio(at)umcervantes(dot)cl>
Cc: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Funcion de Agregacion
Date: 2006-05-02 17:10:55
Message-ID: 4457929F.4020704@galilea.cl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

Juan Martínez wrote:
> El mar, 02-05-2006 a las 12:22 -0400, victor benitez escribió:
>
>> Estimados Listeros:
>>
>> Quisiera saber si alguien sabe como hacer una funcion de agregacion
>> para calcular la moda (El valor mas repetido de una muestra).
>>
>
> Mmm...algo asi puede servir:
>
> SELECT max(subtotal)
> FROM (SELECT descripcion_valor,count(valor) as subtotal
> FROM tabla
> GROUP BY descripcion_valor) AS tabla_1;
>
Probe con eso, pero para graficar el problema aca va un ejemplo,
suponiendo que la Agregacion seria "moda"

select descripcion, to_char(fecha,'DD/MM') as mes , moda(valor) from
tabla group by descripcion, mes;

--
Este mensaje ha sido analizado por nuestros servidores
en busca de virus y otros contenidos peligrosos,
y se considera que est limpio.

Attachment Content-Type Size
vbenitez.vcf text/x-vcard 93 bytes

From: Martin Marques <martin(at)bugs(dot)unl(dot)edu(dot)ar>
To: victor benitez <vbenitez(at)galilea(dot)cl>
Cc: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Funcion de Agregacion
Date: 2006-05-02 17:43:49
Message-ID: 229009133b3167875c9db7acdf359e88@localhost
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda


On Tue, 02 May 2006 12:22:55 -0400, victor benitez <vbenitez(at)galilea(dot)cl> wrote:
> Estimados Listeros:
>
> Quisiera saber si alguien sabe como hacer una funcion de agregacion
> para calcular la moda (El valor mas repetido de una muestra).
>
> logre hacer algo con una tabla temporal, en la cual guardo el valor
> y la cantidad de veces que se repite, y de esto saco el que mas se
> repite, pero no es lo mas optimo.

CREATE OR REPLACE FUNCTION moda() RETURNS INT AS $$
SELECT max(micampo) FROM mitabla;
$$ LANGUAGE SQL;

--
---------------------------------------------------------
Lic. Martín Marqués | SELECT 'mmarques' ||
Centro de Telemática | '@' || 'unl.edu.ar';
Universidad Nacional | DBA, Programador,
del Litoral | Administrador
---------------------------------------------------------


From: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
To: Martin Marques <martin(at)bugs(dot)unl(dot)edu(dot)ar>
Cc: victor benitez <vbenitez(at)galilea(dot)cl>, pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Funcion de Agregacion
Date: 2006-05-02 18:29:31
Message-ID: 20060502182931.GE15291@surnet.cl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

Martin Marques escribió:
>
> On Tue, 02 May 2006 12:22:55 -0400, victor benitez <vbenitez(at)galilea(dot)cl> wrote:

Estimado Victor, perdona por no haber contestado tu mensaje :-( Lo deje
pospuesto para ver si construia la funcion que describo mas abajo, cosa
que no ocurrio :-(

> > Quisiera saber si alguien sabe como hacer una funcion de agregacion
> > para calcular la moda (El valor mas repetido de una muestra).
> >
> > logre hacer algo con una tabla temporal, en la cual guardo el valor
> > y la cantidad de veces que se repite, y de esto saco el que mas se
> > repite, pero no es lo mas optimo.
>
> CREATE OR REPLACE FUNCTION moda() RETURNS INT AS $$
> SELECT max(micampo) FROM mitabla;
> $$ LANGUAGE SQL;

Eso no es la moda. (Ve la definicion de Victor mas arriba).

Entiendo que no hay ninguna manera de calcular la moda haciendo una sola
pasada de los datos, sin exigir una cantidad arbitrariamente grande de
memoria.

Hay dos alternativas:

1. ordenas el conjunto y buscas cual secuencia de valores seguidos es
mas larga. Esto exige dos pasadas sobre los datos: una para ordenar, y
otra para medir el largo de cada secuencia de valores identicos.

2. recorres el arreglo, almacenando para cada valor la cantidad de veces
que lo has visto pasar. Esto se hace en una sola pasada pero puede
requerir mucha memoria.

Si la cantidad de valores distintos no es muy grande, se puede escribir
una funcion de agregacion que use un arreglo como estado de transicion.
Pero no es sencillo, y si hay muchos valores distintos puede incurrir en
un costo muy alto de memoria.

La idea es:
1. el tipo de entrada es el tipo del campo (obvio).
2. el tipo de transicion es un arreglo del tipo de entrada
3. la funcion de transicion es asi:
- si el valor de transicion es nulo, inicializar el arreglo como
(n, 1) donde n es el valor recibido
- si el valor de transicion no es nulo, buscar el valor n en el
arreglo. Si esta, sumar 1 al valor de la posicion siguiente. Si
no esta, agregar al final del arreglo el par (n, 1)
4. la funcion final debe recorrer el arreglo de transicion, buscar el
valor que tiene el contador mas alto, y retornar ese valor.

Lamentablemente, ahora que veo esto, me doy cuenta que solo funciona
cuando el tipo de entrada es numerico. Quizas podrias hacerlo para
otros tipos de datos, usando un tipo compuesto asi:

create type tipo_para_moda (a anyelement, b integer)

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


From: Martin Marques <martin(at)bugs(dot)unl(dot)edu(dot)ar>
To: victor benitez <vbenitez(at)galilea(dot)cl>
Cc: Juan Martínez <jeugenio(at)umcervantes(dot)cl>, pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Funcion de Agregacion
Date: 2006-05-02 18:40:41
Message-ID: 25062f91d51313b1fc685edfa6df2198@localhost
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda


On Tue, 02 May 2006 13:10:55 -0400, victor benitez <vbenitez(at)galilea(dot)cl> wrote:
> Juan Martínez wrote:
>>
>> SELECT max(subtotal)
>> FROM (SELECT descripcion_valor,count(valor) as subtotal
>> FROM tabla
>> GROUP BY descripcion_valor) AS tabla_1;
>>
> Probe con eso, pero para graficar el problema aca va un ejemplo,
> suponiendo que la Agregacion seria "moda"
>
> select descripcion, to_char(fecha,'DD/MM') as mes , moda(valor) from
> tabla group by descripcion, mes;

1) Ignoren la barrabasada que escribi en el mail anterior.
2) La moda es lo que devuelve la consulta que te paso Juan, por lo tanto tendrias que hacer algo asi:

SELECT descripcion_valor,count(valor) as subtotal
FROM tabla
GROUP BY descripcion_valor ORDER BY subtotal LIMIT 1;

--
---------------------------------------------------------
Lic. Martín Marqués | SELECT 'mmarques' ||
Centro de Telemática | '@' || 'unl.edu.ar';
Universidad Nacional | DBA, Programador,
del Litoral | Administrador
---------------------------------------------------------


From: Juan Martínez <jeugenio(at)umcervantes(dot)cl>
To: victor benitez <vbenitez(at)galilea(dot)cl>
Cc: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Funcion de Agregacion
Date: 2006-05-02 20:30:36
Message-ID: 1146601836.7355.26.camel@localhost.localdomain
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

El mar, 02-05-2006 a las 13:10 -0400, victor benitez escribió:
> Juan Martínez wrote:
> > El mar, 02-05-2006 a las 12:22 -0400, victor benitez escribió:
> >
> >> Estimados Listeros:
> >>
> >> Quisiera saber si alguien sabe como hacer una funcion de agregacion
> >> para calcular la moda (El valor mas repetido de una muestra).
> >>
> >
> > Mmm...algo asi puede servir:
> >
> > SELECT max(subtotal)
> > FROM (SELECT descripcion_valor,count(valor) as subtotal
> > FROM tabla
> > GROUP BY descripcion_valor) AS tabla_1;
> >
> Probe con eso, pero para graficar el problema aca va un ejemplo,
> suponiendo que la Agregacion seria "moda"
>
> select descripcion, to_char(fecha,'DD/MM') as mes , moda(valor) from
> tabla group by descripcion, mes;

Tu quieres una moda (o sea en teoria un max(count(valor)) ) por
descripcion y mes? Suponiendo que las descripciones son todas distintas,
y las fechas tambien, le causaras un gran dolor de cpu al pobre
computador...

Puedes ser mas especifico con el calculo que buscas?

--
Juan Martínez
Depto. Inf.
UMC