Skip site navigation (1) Skip section navigation (2)

Re: Obtener los 3 valores mas altos por grupo de una serie de registros

From: Raúl Andrés Duque Murillo <ra_duque(at)yahoo(dot)com(dot)mx>
To: Oswaldo Hernández <listas(at)soft-com(dot)es>,"Alejandro D(dot) Burne" <alejandro(dot)dburne(at)gmail(dot)com>
Cc: "PostgreEs" <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Obtener los 3 valores mas altos por grupo de una serie de registros
Date: 2008-09-21 13:20:44
Message-ID: 75CD7696C1254655BDC5633BBFF3A383@Principal (view raw or flat)
Thread:
Lists: pgsql-es-ayuda

--------------------------------------------------
From: "Oswaldo Hernández" <listas(at)soft-com(dot)es>
Sent: Sunday, September 21, 2008 7:37 AM
To: "Alejandro D. Burne" <alejandro(dot)dburne(at)gmail(dot)com>
Cc: "PostgreEs" <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: [pgsql-es-ayuda] Obtener los 3 valores mas altos por grupo de 
una serie de registros

> Alejandro D. Burne escribió:
>> Alguien tiene idea de como armar una consulta sql (si es que se puede)
>> para obtener los 3 valores máximos y agrupandolos por una determinada
>> columna, por ejemplo teniendo los siguientes datos:
>>
>
> Posible es, pero dudo mucho de la eficiencia con tablas grandes.
>
> postgres=# CREATE TABLE pruebas.test3 (c1 integer NOT NULL, c2 integer NOT 
> NULL);
> CREATE TABLE
> postgres=# insert into pruebas.test3 values
> postgres-#     (1,1),(1,2),(1,3),(1,4),(1,5),
> postgres-#     (2,1),(2,2),(2,3),(2,4),(2,5),
> postgres-#     (3,1),(3,2),(3,3),(3,4),(3,5),(3,5),
> postgres-#     (4,1),(4,1),(4,5),(4,5),(4,5);
> INSERT 0 21
> postgres=# select t3.c1, t3.c2
> postgres-# from pruebas.test3 t3
> postgres-# where
> postgres-#     (select count(*) from
> postgres(#         (select * from pruebas.test3 g3 group by g3.c1, g3.c2) 
> w3
> postgres(#         where w3.c1 = t3.c1 and w3.c2 > t3.c2
> postgres(#     ) < 3
> postgres-# group by t3.c1, t3.c2
> postgres-# order by t3.c1, t3.c2 desc;
>  c1 | c2
> ----+----
>   1 |  5
>   1 |  4
>   1 |  3
>   2 |  5
>   2 |  4
>   2 |  3
>   3 |  5
>   3 |  4
>   3 |  3
>   4 |  5
>   4 |  1
> (11 filas)
>

Alejandro, la solución que planteas funciona siempre y cuando NO EXISTAN 
"c2" repetidos. Para probarlo llena la tabla con los siguientes datos:

insert into test3 values
(1,1),(1,2),(1,3),(1,4),(1,5), (1,5),
(2,1),(2,2),(2,3),(2,4),(2,5), (2,5),
(3,1),(3,2),(3,3),(3,4),(3,5),(3,5),
(4,1),(4,1),(4,5),(4,5),(4,5);

Nota que (1, 5) y (2, 5) estan repetidos. El select que planteas sigue dando 
el mismo resultado, cuando el 5 debería aparecer dos veces para el "c1" 1 y 
2.

"me acabo de dar cuenta que el (4,5) estaba repetido y no necesitaba 
adicionar nuevas filas :-)"

Se me ocurre la siguiente solución, con índices por c1 y c2 debería reponder 
aceptablemente:

select c1, max(c2) as c2
from test3
group by c1
union all
select c1, (select c2 from test3 where c1 = aux.c1 order by c2 desc limit 1 
offset 1) as c2
from test3 aux
group by c1
union all
select c1, (select c2 from test3 where c1 = aux.c1 order by c2 desc limit 1 
offset 2) as c2
from test3 aux
group by c1

RESULTADO:
4;5
2;5
3;5
1;5
4;5
2;5
3;5
1;5
4;5
2;4
3;4
1;4

Si quieres que salga ordenado puedes agregar la sentencia dentro de un 
subquery en el from y hacer un order by, pero ten en cuenta que le aumentará 
complejidad/tiempo a tu consulta y no siempre será necesario este 
ordenamiento.

Atentamente,

RAUL DUQUE
Bogotá, Colombia

>
>
> Saludos,
>
> -- 
> *****************************************
> Oswaldo Hernández
> oswaldo (@) soft-com (.) es
> *****************************************
> PD:
> Antes de imprimir este mensaje, asegúrese de que es necesario.
> El medio ambiente está en nuestra mano.
> --
> TIP 6: ¿Has buscado en los archivos de nuestra lista de correo?
>               http://archives.postgresql.org/pgsql-es-ayuda
>
> __________ Information from ESET Smart Security, version of virus 
> signature database 3458 (20080921) __________
>
> The message was checked by ESET Smart Security.
>
> http://www.eset.com
>
> 

In response to

Responses

pgsql-es-ayuda by date

Next:From: Oswaldo HernándezDate: 2008-09-21 17:20:18
Subject: Re: Obtener los 3 valores mas altos por grupo de una serie de registros
Previous:From: Oswaldo HernándezDate: 2008-09-21 12:37:47
Subject: Re: Obtener los 3 valores mas altos por grupo de una serie de registros

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group