Uso de Offset y Fetch Next en SQL Server

Usando OffSet y Fetch next en Select

La instrucción Select (Ver Select) tiene varias opciones que se pueden incluir según las necesidades de la presentación de la información extraída de una o más tablas.
En ocasiones es necesario mostrar los registros en un determinado orden, para ello podemos usar la cláusula Order by (Ver Ordenamientos), lo que permitirá mostrar el resultado obtenido con un orden especificado, y de acuerdo a uno o más campos.

Como usar Offset en SQL Server

Offset n Rows permite en un listado que se muestra de manera ordenada no tener en cuenta los n registros que se muestran al inicio del listado, Offset n Rows se utiliza después de la cláusula Order by donde el valor n especifica la cantidad de registros a no tener en cuenta.

Ejemplos

Usando la base de datos Northwind
use Northwind
go

Ejercicio 1

Listar los productos ordenados por stock en orden descendente
Select P.ProductID As ‘Código’, P.ProductName As ‘Descripción’,
P.UnitPrice As ‘Precio’, P.UnitsInStock As ‘Stock’
from Products As P
order by P.UnitsInStock desc
go
Se puede notar que aparecen todos los productos ordenados por unidades en Stock. En la imagen se han marcado los 5 primeros registros que no se tendrán en cuenta en la siguiente instrucción usando OffSet

Para no presentar en el listado los cinco primeros productos con mayor stock podemos usar la cláusula Offset especificando 5 registros (OffSet 5 rows). Note que el sexto registro es el que tiene el código 33.
Select P.ProductID As ‘Código’, P.ProductName As ‘Descripción’,
P.UnitPrice As ‘Precio’, P.UnitsInStock As ‘Stock’
from Products As P
order by P.UnitsInStock desc
Offset 5 Rows
go

Ejercicio 2

Listar los productos que se vendieron mas en 1997, no tenga en cuenta los 10 primeros. (Ver Joins) (Ver Agrupamientos) (Ver Funciones de agregado). Primero mostrar todos los productos
Select P.ProductID As ‘Código’, P.ProductName As ‘Descripción’,
P.UnitPrice As ‘Precio’, P.UnitsInStock As ‘Stock’,
sum(D.Quantity) As ‘Cantidad Vendida’
from Products As P
join [Order Details] As D on P.ProductID = D.ProductID
join Orders As O on O.OrderID = D.OrderID
Where Year(O.OrderDate) = 1997
Group by P.ProductID , P.ProductName, P.UnitPrice, P.UnitsInStock
order by [Cantidad Vendida] desc
go

Ahora se incluye la opción Offset 10 rows para que los 10 primeros no sean tomados en cuenta.
Select P.ProductID As ‘Código’, P.ProductName As ‘Descripción’,
P.UnitPrice As ‘Precio’, P.UnitsInStock As ‘Stock’,
sum(D.Quantity) As ‘Cantidad Vendida’
from Products As P
join [Order Details] As D on P.ProductID = D.ProductID
join Orders As O on O.OrderID = D.OrderID
Where Year(O.OrderDate) = 1997
Group by P.ProductID , P.ProductName, P.UnitPrice, P.UnitsInStock
order by [Cantidad Vendida] desc
Offset 10 rows
go

Los productos que no se presentan son los 10 que tienen mas venta, para mostrarlos podemos usar la cláusula Top (Ver Select – Opciones)
Select Top 10
P.ProductID As ‘Código’, P.ProductName As ‘Descripción’,
P.UnitPrice As ‘Precio’, P.UnitsInStock As ‘Stock’,
sum(D.Quantity) As ‘Cantidad Vendida’
from Products As P
join [Order Details] As D on P.ProductID = D.ProductID
Group by P.ProductID , P.ProductName, P.UnitPrice, P.UnitsInStock
order by [Cantidad Vendida] desc
go

Como usar Fetch next n rows only

Para listar los registros teniendo en cuenta un orden específico e incluir una cantidad determinada de estos se puede usar la cláusula Fetch next n Rows only, lo que permitirá especificar cuantos registros se desea mostrar, exceptuando los primeros que no se presentan usando Offset n Rows

Ejercicio 3

Listar los empleados y la cantidad de órdenes generadas, no mostrar los 4 primeros e incluir solamente tres registros en el listado. Ver Función Concat_ws

Primero vamos a ver el listado completo de los empleados y la cantidad de órdenes.
Select E.EmployeeID As ‘Cód. Empleado’,
CONCAT_WS(‘, ‘,E.LastName,E.FirstName) As ‘Empleado’,
COUNT(O.OrderID) As ‘Cantidad de Órdenes’
from Employees As E
join Orders As O on E.EmployeeID = O.EmployeeID
Group by E.EmployeeID, CONCAT_WS(‘, ‘,E.LastName,E.FirstName)
order by [Cantidad de Órdenes] desc
go

Ahora el listado no tendrá en cuenta los 4 primeros y se va a listar únicamente los siguientes 3 registros.
Select E.EmployeeID As ‘Cód. Empleado’,
CONCAT_WS(‘, ‘,E.LastName,E.FirstName) As ‘Empleado’,
COUNT(O.OrderID) As ‘Cantidad de Órdenes’
from Employees As E
join Orders As O on E.EmployeeID = O.EmployeeID
Group by E.EmployeeID, CONCAT_WS(‘, ‘,E.LastName,E.FirstName)
order by [Cantidad de Órdenes] desc
Offset 4 rows fetch next 3 rows only
go
Compare las dos imágenes anteriores y puede notar que no se muestran los 4 primeros y luego se muestran los siguientes tres registros.