Encontrar top n para cada fila única
-
06-07-2019 - |
Pregunta
Estoy tratando de obtener los N registros superiores para cada fila única de datos en una tabla (estoy agrupando en las columnas b , c y d , la columna a es el identificador único y la columna e es la puntuación de la que quiero el primer 1 en este caso).
a b c d e
2 38 NULL NULL 141
1 38 NULL NULL 10
1 38 1 NULL 10
2 38 1 NULL 1
1 38 1 8 10
2 38 1 8 1
2 38 16 NULL 140
2 38 16 12 140
p. de estos datos me gustaría encontrar las siguientes filas:
a b c d e
2 38 NULL NULL 141
1 38 1 NULL 10
1 38 1 8 10
2 38 16 NULL 140
2 38 16 12 140
¿alguien puede señalarme en la dirección correcta para resolver esto?
Solución
Tu ejemplo no se muestra y no explicas cómo determinas qué fila es la " top " uno, así que he puesto ?????? en la consulta donde necesita proporcionar una columna de clasificación, como
a desc
por ejemplo. En cualquier caso, esto es exactamente para lo que sirven las funciones analíticas en SQL Server 2005 y posteriores.
declare @howmany int = 3;
with TRanked (a,b,c,d,e,rk) as (
select
a,b,c,d,e,
rank() over (
partition by b,c,d
order by ???????
)
from T
)
select a,b,c,d,e
from TRanked
where rk <= @howmany;
Otros consejos
Los nulos son un dolor, pero algo como esto:
select * from table1 t1
where a in (
select top 1 a from table1 t2
where (t1.b = t2.b or (t1.b is null and t2.b is null))
and (t1.c = t2.c or (t1.c is null and t2.c is null))
and (t1.d = t2.d or (t1.d is null and t2.d is null))
order by e desc
)
o mejor aún:
select * from (
select *, seqno = row_number() over (partition by b, c, d order by e desc)
from table1
) a
where seqno = 1
Creo que esto hará lo que usted dijo (extendiendo la idea de aquí ):
select b,c,d,e,
rank() over
(partition by b,c,d order by e desc) "rank"
from t1 where rank < 5
Saludos.