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?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top