En iyi yanıtlayıcılar
Obtener top 10, en un rango de x numero de registros

Soru
-
Buen dia a todos, tengo 2 tablas, de las cuales al unirlas obtengo aproximadamente 80 registros de la siguiente manera:
SELECT IdEmp, NameEmp, SUM(Tot) AS Total FROM HorasLaboradas INNER JOIN empleados ON empleados.NumEmp = HorasLaboradas.NumEmpl GROUP BY IdEmp, NameEmp ORDER BY Total DESC
Hasta aqui todo bien, obtengo todos los empleados con su nombre y un total de horas.
Aqui es donde tengo la siguiente duda:
Tengo un numero de empleado, y deseo obtener los 5 registros anteriores y los 5 registros posteriores del usuario que estoy buscando, es decir un top 10, pero apartir de un empleado, esto es para obtener una lista de 10 empleados, pero siempre debe aparecer el usuario que busco.
Por ejemplo si buscara al empleado 500 pero apareceria en la posicion 25, tendria q obtener un top entre la posicion 10 y 30
Posicion NumeroEmpleado Total
20 235 65
21 120 60
22 050 58
22 003 55
23 355 50
24 189 45
25 500 40
26 001 35
27 100 30
28 380 27
29 070 25
30 200 20
Pueden guiarme sobre si es posible realizar esto en una sentencia sql?, o pueden quiarme?, uso sql server 2012.
Yanıtlar
-
Podrías usar la cláusula OVER junto con "... ROWS BETWEEN 5 PRECEDING AND 5 FOLLOWING". Precisamente se introdujo por primera vez con la versión 2012 de SQL Server, que es justo la que tienes.
- Yanıt Olarak İşaretleyen Pollokullos 25 Kasım 2019 Pazartesi 18:01
Tüm Yanıtlar
-
Podrías usar la cláusula OVER junto con "... ROWS BETWEEN 5 PRECEDING AND 5 FOLLOWING". Precisamente se introdujo por primera vez con la versión 2012 de SQL Server, que es justo la que tienes.
- Yanıt Olarak İşaretleyen Pollokullos 25 Kasım 2019 Pazartesi 18:01
-
-
Tengo un numero de empleado, y deseo obtener los 5 registros anteriores y los 5 registros posteriores del usuario que estoy buscando,
Pruebe
-- código #1 declare @Empleado int, @posicion int; set @Empleado= 500; -- IF Object_ID('tempDB..#rank_empleado', 'U') is not null DROP TABLE #rank_empleado; -- SELECT IdEmp, NameEmp, SUM(Tot) AS Total, posicion= row_number() over (partition by IdEmp
order by SUM(Tot) desc, NameEmp asc) INTO #rank_empleado FROM HorasLaboradas INNER JOIN empleados ON empleados.NumEmp = HorasLaboradas.NumEmpl GROUP BY IdEmp, NameEmp;
CREATE unique clustered INDEX I1_rank on #rank_empleado (posicion);
-- set @posicion= (SELECT top (1) posicion from #rank_empleado where IdEmp = @Empleado); SELECT posicion, IdEmp, NameEmp, Total from #rank_empleado where posicion between (@posicion -5) and (@posicion +5)
order by posicion, NameEmp; -- IF Object_ID('tempDB..#rank_empleado', 'U') is not null DROP TABLE #rank_empleado;o
-- código #2 declare @Empleado int, @posicion int; set @Empleado= 500; -- with Calculo as ( SELECT IdEmp, NameEmp, SUM(Tot) AS Total, posicion= row_number() over (partition by IdEmp
order by SUM(Tot) desc, NameEmp asc) FROM HorasLaboradas INNER JOIN empleados ON empleados.NumEmp = HorasLaboradas.NumEmpl GROUP BY IdEmp, NameEmp ) SELECT top (11) posicion, IdEmp, NameEmp, Total from Calculo where posicion >= (SELECT posicion from Calculo where IdEmp = @Empleado) -5;Use el código # 2 solo para pequeños volúmenes de datos.
Si esta respuesta te ayudó a resolver tu problema, recuerda marcarla.
José Diz Belo Horizonte, MG - Brasil [T-SQL performance tuning: Porto SQL] [e-mail]
Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.
- Düzenleyen José Diz 18 Ağustos 2019 Pazar 16:35