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 |
Thread: | |
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 | Date | Subject | |
---|---|---|---|
Next Message | Martin Marques | 2006-05-02 18:40:41 | Re: Funcion de Agregacion |
Previous Message | Pablo Braulio | 2006-05-02 18:13:20 | Re: Contar registros insertados por mes. |