TOP (Transact-SQL)

Limita las filas devueltas en un conjunto de resultados de la consulta a un número o porcentaje de filas especificado en SQL Server 2012. Cuando se usa TOP junto con la cláusula ORDER BY, el conjunto de resultados se limita al primer número N de filas ordenadas; de lo contrario, devuelve el primer número N de filas en un orden no definido. Utilice esta cláusula para especificar el número de filas devueltas de una instrucción SELECT o afectadas por una instrucción INSERT, UPDATE, MERGE o DELETE.

Icono de vínculo a temas Convenciones de sintaxis de Transact-SQL

Sintaxis

[ 
    TOP (expression) [PERCENT]
    [ WITH TIES ]
]

Argumentos

  • expression
    Es la expresión numérica que especifica el número de filas que se devolverán. El valor expression se convierte implícitamente a un valor float si se especificó PERCENT; de lo contrario, se convierte a bigint.

  • PERCENT
    Indica que la consulta devuelve sólo el primer porcentaje de filas de expression del conjunto de resultados. Los valores fraccionarios se redondean al siguiente valor entero.

  • WITH TIES
    Se usa cuando se desean devolver dos o más filas que ocupan el último lugar en el conjunto de resultados limitado. Debe usarse con la cláusula ORDER BY. WITH TIES puede hacer que se devuelvan más filas que el valor especificado en expression. Por ejemplo, si expression está establecido en 5, pero 2 filas adicionales coinciden con los valores de las columnas ORDER BY en la fila 5, el conjunto de resultados contendrá 7 filas.

    TOP...WITH TIES solo se puede especificar en instrucciones SELECT y siempre que se haya especificado una cláusula ORDER BY. El orden devuelto de los registros enlazados es arbitrario. ORDER BY no afecta a esta regla.

Procedimientos recomendados

En una instrucción SELECT, utilice siempre una cláusula ORDER BY con la cláusula TOP. Esta es la única manera de indicar previsiblemente a qué filas afecta TOP.

Utilice OFFSET y FETCH en la cláusula ORDER BY en lugar de la cláusula TOP para implementar una solución de paginación de consulta. Una solución de paginación (es decir, el envío de fragmentos o "páginas" de datos al cliente) es más fácil de implementar mediante OFFSET y FETCH. Para obtener más información, vea ORDER BY (cláusula de Transact-SQL).

Utilice TOP (o bien, OFFSET y FETCH) en lugar de SET ROWCOUNT para limitar el número de filas devueltas. Estos métodos son preferibles a utilizar SET ROWCOUNT por las siguientes razones:

  • Como parte de una instrucción SELECT, el optimizador de consultas puede considerar el valor de expression en las cláusulas TOP o FETCH durante la optimización de la consulta. Dado que SET ROWCOUNT se usa fuera de una instrucción que ejecuta una consulta, su valor no se puede considerar en un plan de consulta.

Soporte de compatibilidad

Por compatibilidad con versiones anteriores, los paréntesis son opcionales en las instrucciones SELECT. Se recomienda utilizar siempre los paréntesis para TOP en las instrucciones SELECT por coherencia con su uso necesario en las instrucciones INSERT, UPDATE, MERGE y DELETE, en las que se requieren los paréntesis.

Interoperabilidad

La expresión TOP no afecta a las instrucciones que se pueden ejecutar debido a un desencadenador. Las tablas inserted y deleted en los desencadenadores solo mostrarán las filas verdaderamente afectadas por las instrucciones INSERT, UPDATE, MERGE o DELETE. Por ejemplo, si INSERT TRIGGER se desencadena como resultado de una instrucción INSERT que utilizó una cláusula TOP,

SQL Server permite actualizar las filas a través de las vistas. Dado que la cláusula TOP puede estar incluida en la definición de vista, es posible que algunas filas desaparezcan de la vista a causa de una actualización si las filas ya no cumplen con los requisitos de la expresión TOP.

Cuando se especifica en la instrucción MERGE, la cláusula TOP se aplica después de que se combinen la tabla de origen completa y la tabla de destino completa y de que se quiten las filas combinadas que no certifican las acciones de inserción, actualización o eliminación. La cláusula TOP reduce aún más el número de filas combinadas hasta el valor especificado y se aplican las acciones de inserción, actualización o eliminación a las filas combinadas restantes de una manera desordenada. Es decir, no hay ningún orden en el que las filas se distribuyan entre las acciones definidas en las cláusulas WHEN. Por ejemplo, si especificar TOP (10) afecta a 10 filas; de estas filas, se pueden actualizar 7 e insertar 3, o se pueden eliminar 1, actualizar 5 e insertar 4, etc. Dado que la instrucción MERGE realiza exámenes de tabla completos de ambas tablas, de destino y de origen, el rendimiento de E/S puede verse afectado al utilizar la cláusula TOP para modificar una tabla grande mediante la creación de varios lotes. En este escenario, es importante asegurase de que todos los lotes sucesivos tengan como destino nuevas filas.

Tenga precaución al especificar la cláusula TOP en una consulta que contiene un operador UNION, UNION ALL, EXCEPT o INTERSECT. Es posible escribir una consulta que devuelva resultados inesperados porque el orden en el que se procesan lógicamente las cláusulas TOP y ORDER BY no siempre es intuitivo cuando estos operadores se utilizan en una operación Select. Por ejemplo, dados los siguientes datos y la siguiente tabla, suponga que desea devolver el coche rojo menos caro y el coche azul menos caro. Es decir, el sedán rojo y la camioneta azul.

CREATE TABLE dbo.Cars(Model varchar(15), Price money, Color varchar(10));
INSERT dbo.Cars VALUES
    ('sedan', 10000, 'red'), ('convertible', 15000, 'blue'), 
    ('coupe', 20000, 'red'), ('van', 8000, 'blue');

Para lograr estos resultados, podría escribir la siguiente consulta.

SELECT TOP(1) Model, Color, Price
FROM dbo.Cars
WHERE Color = 'red'
UNION ALL
SELECT TOP(1) Model, Color, Price
FROM dbo.Cars
WHERE Color = 'blue'
ORDER BY Price ASC;

El conjunto de resultados es el siguiente.

Model         Color      Price

------------- ---------- -------

sedan         red        10000.00

convertible   blue       15000.00

Se devuelven resultados inesperados porque la cláusula TOP se ejecuta lógicamente antes que la cláusula ORDER BY, que ordena los resultados del operador (UNION ALL en este caso). Así, la consulta anterior devuelve cualquier coche rojo y cualquier coche azul y, a continuación, ordena el resultado de esa unión por el precio. En el siguiente ejemplo se muestra el método correcto de escribir esta consulta para lograr el resultado deseado.

SELECT Model, Color, Price
FROM (SELECT TOP(1) Model, Color, Price
      FROM dbo.Cars
      WHERE Color = 'red'
      ORDER BY Price ASC) AS a
UNION ALL
SELECT Model, Color, Price
FROM (SELECT TOP(1) Model, Color, Price
      FROM dbo.Cars
      WHERE Color = 'blue'
      ORDER BY Price ASC) AS b;

Utilizando TOP y ORDER BY en una operación de subselección, se puede asegurar de que los resultados de la cláusula ORDER BY que se utilizan se apliquen a la cláusula TOP y no a ordenar el resultado de la operación UNION.

El conjunto de resultados es el siguiente.

Model         Color      Price

------------- ---------- -------

sedan         red        10000.00

van           blue        8000.00

Limitaciones y restricciones

Cuando se utiliza TOP con INSERT, UPDATE, MERGE o DELETE, las filas a las que hace referencia no están organizadas de ninguna manera y la cláusula ORDER BY no se puede especificar directamente en estas instrucciones. Si necesita usar TOP para insertar, eliminar o modificar las filas en un orden cronológico significativo, debe utilizar TOP junto con una cláusula ORDER BY que se especifica en una instrucción de subselección. Vea la sección Ejemplos que aparece más adelante en este tema.

TOP no se puede usar en las instrucciones UPDATE y DELETE en vistas con particiones.

TOP no se puede combinar con OFFSET y FETCH en la misma expresión de consulta (en el mismo ámbito de la consulta). Para obtener más información, vea ORDER BY (cláusula de Transact-SQL).

Ejemplos

Categoría

Elementos de sintaxis ofrecidos

Sintaxis básica

TOP • PERCENT

Incluir valores equivalentes

WITH TIES

Limitar las filas afectadas por DELETE, INSERT o UPDATE

DELETE • INSERT • UPDATE

Sintaxis básica

En los ejemplos de esta sección se muestra la funcionalidad básica de la cláusula ORDER BY utilizando la sintaxis mínima requerida.

A. Utilizar TOP con un valor constante

En los siguientes ejemplos se utiliza un valor constante para especificar el número de empleados que se devuelven en el conjunto de resultados de la consulta. En el primer ejemplo, se devuelven las 10 primeras filas sin definir porque no se usa una cláusula ORDER BY. En el segundo ejemplo, se utiliza una cláusula ORDER BY para devolver los primeros 10 empleados contratados recientemente.

USE AdventureWorks2012;
GO
-- Select the first 10 random employees.
SELECT TOP(10)JobTitle, HireDate
FROM HumanResources.Employee;
GO
-- Select the first 10 employees hired most recently.
SELECT TOP(10)JobTitle, HireDate
FROM HumanResources.Employee
ORDER BY HireDate DESC;

B. Utilizar TOP con una variable

En el siguiente ejemplo se utiliza una variable para especificar el número de empleados que se devuelven en el conjunto de resultados de la consulta.

USE AdventureWorks2012;
GO
DECLARE @p AS int = 10;
SELECT TOP(@p)JobTitle, HireDate, VacationHours
FROM HumanResources.Employee
ORDER BY VacationHours DESC
GO

C. Especificar un porcentaje

En el siguiente ejemplo se utiliza PERCENT para especificar el número de empleados que se devuelven en el conjunto de resultados de la consulta. Hay 290 empleados en la tabla HumanResources.Employee. Dado que el 5 por ciento de 290 es un valor fraccionario, el valor se redondea al número entero siguiente.

USE AdventureWorks2012;
GO
SELECT TOP(5)PERCENT JobTitle, HireDate
FROM HumanResources.Employee
ORDER BY HireDate DESC;

Incluir valores equivalentes

A. Utilizar WITH TIES para incluir las filas que coinciden con los valores de la última fila

En el ejemplo siguiente se obtiene el primer 10 por ciento de los empleados que tienen los salarios más altos y se devuelven en orden descendente de acuerdo con su salario. La especificación de WITH TIES garantiza que también se incluyan en el conjunto de resultados los empleados con salarios iguales al salario más bajo devuelto (la última fila), aun cuando esto exceda el 10 por ciento de los empleados.

USE AdventureWorks2012;
GO
SELECT TOP(10)WITH TIES
pp.FirstName, pp.LastName, e.JobTitle, e.Gender, r.Rate
FROM Person.Person AS pp 
    INNER JOIN HumanResources.Employee AS e
        ON pp.BusinessEntityID = e.BusinessEntityID
    INNER JOIN HumanResources.EmployeePayHistory AS r
        ON r.BusinessEntityID = e.BusinessEntityID
ORDER BY Rate DESC;

Limitar las filas afectadas por DELETE, INSERT o UPDATE

A. Utilizar TOP para limitar el número de filas eliminadas

Cuando se usa una cláusula TOP (n) con DELETE, la operación de eliminación se realiza en una selección sin definir de n número de filas. Es decir, la instrucción DELETE elige cualquier número (n) de filas que cumplen los criterios definidos en la cláusula WHERE. En el ejemplo siguiente se eliminan 20 filas de la tabla PurchaseOrderDetail cuyas fechas de vencimiento son anteriores al 1 de julio de 2002.

USE AdventureWorks2012;
GO
DELETE TOP (20) 
FROM Purchasing.PurchaseOrderDetail
WHERE DueDate < '20020701';
GO

Si necesita utilizar TOP para eliminar filas por un orden cronológico significativo, debe utilizarla junto con ORDER BY en una instrucción de subselección. La siguiente consulta elimina de la tabla PurchaseOrderDetail las 10 filas con las fechas de vencimiento más antiguas. Para garantizar que solo se eliminen 10 filas, la columna especificada en la instrucción de subselección (PurchaseOrderID) es la clave principal de la tabla. El uso de una columna sin clave en la instrucción de subselección podría causar la eliminación de más de 10 filas si la columna especificada contiene valores duplicados.

USE AdventureWorks2012;
GO
DELETE FROM Purchasing.PurchaseOrderDetail
WHERE PurchaseOrderDetailID IN
   (SELECT TOP 10 PurchaseOrderDetailID 
    FROM Purchasing.PurchaseOrderDetail 
    ORDER BY DueDate ASC);
GO

B. Utilizar TOP para limitar el número de filas insertadas

En el ejemplo siguiente se crea la tabla EmployeeSales y se inserta el nombre y los datos de ventas del año hasta la fecha para los 5 primeros empleados de la tabla HumanResources.Employee. La instrucción INSERT elige 5 filas cualesquiera devuelvas por la instrucción SELECT que cumplen los criterios definidos en la cláusula WHERE. La cláusula OUTPUT muestra las filas que se insertan en la tabla EmployeeSales. Observe que la cláusula ORDER BY de la instrucción SELECT no se utiliza para determinar los primeros 5 empleados.

USE AdventureWorks2012 ;
GO
IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NOT NULL
    DROP TABLE dbo.EmployeeSales;
GO
CREATE TABLE dbo.EmployeeSales
( EmployeeID   nvarchar(11) NOT NULL,
  LastName     nvarchar(20) NOT NULL,
  FirstName    nvarchar(20) NOT NULL,
  YearlySales  money NOT NULL
 );
GO
INSERT TOP(5)INTO dbo.EmployeeSales
    OUTPUT inserted.EmployeeID, inserted.FirstName, inserted.LastName, inserted.YearlySales
    SELECT sp.BusinessEntityID, c.LastName, c.FirstName, sp.SalesYTD 
    FROM Sales.SalesPerson AS sp
    INNER JOIN Person.Person AS c
        ON sp.BusinessEntityID = c.BusinessEntityID
    WHERE sp.SalesYTD > 250000.00
    ORDER BY sp.SalesYTD DESC;

Si necesita usar TOP para insertar las filas en un orden cronológico significativo, debe utilizar TOP junto con ORDER BY en una instrucción de subselección, tal y como se muestra en el siguiente ejemplo. La cláusula OUTPUT muestra las filas que se insertan en la tabla EmployeeSales. Observe que los 5 primeros empleados se insertan ahora según los resultados de la cláusula ORDER BY en lugar de las filas sin definir.

INSERT INTO dbo.EmployeeSales
    OUTPUT inserted.EmployeeID, inserted.FirstName, inserted.LastName, inserted.YearlySales
    SELECT TOP (5) sp.BusinessEntityID, c.LastName, c.FirstName, sp.SalesYTD 
    FROM Sales.SalesPerson AS sp
    INNER JOIN Person.Person AS c
        ON sp.BusinessEntityID = c.BusinessEntityID
    WHERE sp.SalesYTD > 250000.00
    ORDER BY sp.SalesYTD DESC;

C. Usar TOP para limitar el número de filas actualizadas

En el ejemplo siguiente se usa la cláusula TOP para actualizar filas de una tabla. Cuando se usa una cláusula TOP (n) con UPDATE, la operación de actualización se realiza sobre un número sin definir de filas. Es decir, la instrucción UPDATE elige cualquier número (n) de filas que cumplen los criterios definidos en la cláusula WHERE. En el ejemplo siguiente se asignan 10 clientes de un vendedor a otro.

USE AdventureWorks2012;
UPDATE TOP (10) Sales.Store
SET SalesPersonID = 276
WHERE SalesPersonID = 275;
GO

Si necesita usar TOP para aplicar actualizaciones según un orden cronológico significativo, debe usar TOP junto con ORDER BY en una instrucción de subselección. En el siguiente ejemplo se actualizan las horas de vacaciones de los 10 empleados cuyas fechas de alta son más antiguas.

UPDATE HumanResources.Employee
SET VacationHours = VacationHours + 8
FROM (SELECT TOP 10 BusinessEntityID FROM HumanResources.Employee
     ORDER BY HireDate ASC) AS th
WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID;
GO

Vea también

Referencia

SELECT (Transact-SQL)

INSERT (Transact-SQL)

UPDATE (Transact-SQL)

DELETE (Transact-SQL)

ORDER BY (cláusula de Transact-SQL)

SET ROWCOUNT (Transact-SQL)

MERGE (Transact-SQL)