Paginación de los resultados de SQL Server 2005

votos
36

¿Cómo puedo obtener los resultados de la página en SQL Server 2005?

Lo intenté en SQL Server 2000, pero no había una manera confiable de hacerlo. Ahora me pregunto si SQL Server 2005 tiene algún método integrado.

Lo que quiero decir con paginación es, por ejemplo, si enumero usuarios por su nombre de usuario, quiero poder devolver solo los primeros 10 registros, luego los 10 registros siguientes y así sucesivamente.

Cualquier ayuda sería muy apreciada.

Publicado el 05/08/2008 a las 21:57
fuente por usuario
En otros idiomas...                            


6 respuestas

votos
33

Puedes usar la the Row_Number()función. Se usa de la siguiente manera:

SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users

De donde obtendrá un conjunto de resultados con un RowIDcampo que puede usar para paginar entre.

SELECT * 
FROM 
    ( SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
      FROM Users 
    ) As RowResults
WHERE RowID Between 5 AND 10

etc

Respondida el 05/08/2008 a las 21:59
fuente por usuario

votos
13

Si está tratando de obtenerlo en una declaración (el total más la paginación). Es posible que necesite explorar el soporte de SQL Server para la cláusula partition by (funciones de ventana en términos ANSI SQL). En Oracle, la sintaxis es igual que en el ejemplo anterior utilizando row_number (), pero también he agregado una cláusula partition by para obtener el número total de filas incluidas con cada fila devuelta en el paginado (el total de filas es 1,262):

SELECT rn, total_rows, x.OWNER, x.object_name, x.object_type
FROM (SELECT COUNT (*) OVER (PARTITION BY owner) AS TOTAL_ROWS,
         ROW_NUMBER () OVER (ORDER BY 1) AS rn, uo.*
         FROM all_objects uo
         WHERE owner = 'CSEIS') x
WHERE rn BETWEEN 6 AND 10

Tenga en cuenta que tengo donde owner = 'CSEIS' y mi partición por está en el propietario. Entonces los resultados son:

RN  TOTAL_ROWS  OWNER   OBJECT_NAME            OBJECT_TYPE
6   1262    CSEIS   CG$BDS_MODIFICATION_TYPES   TRIGGER
7   1262    CSEIS   CG$AUS_MODIFICATION_TYPES   TRIGGER
8   1262    CSEIS   CG$BDR_MODIFICATION_TYPES   TRIGGER
9   1262    CSEIS   CG$ADS_MODIFICATION_TYPES   TRIGGER
10  1262    CSEIS   CG$BIS_LANGUAGES            TRIGGER
Respondida el 14/08/2008 a las 18:15
fuente por usuario

votos
5

La respuesta aceptada para esto en realidad no me funciona ... tuve que saltar un aro más para que funcione.

Cuando intenté la respuesta

SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
WHERE RowID Between 0 AND 9

falló, quejándose de que no sabía qué era RowID.

Tuve que envolverlo en un selecto interno como este:

SELECT * 
FROM
    (SELECT
    Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
    FROM Users
    ) innerSelect
WHERE RowID Between 0 AND 9

y luego funcionó.

Respondida el 15/04/2009 a las 18:56
fuente por usuario

votos
2

Cuando necesito hacer paginación, normalmente también uso una tabla temporal. Puede usar un parámetro de salida para devolver el número total de registros. Las declaraciones de casos en la selección le permiten ordenar los datos en columnas específicas sin necesidad de recurrir a SQL dinámico.

--Declaration--

--Variables
@StartIndex INT,
@PageSize INT,
@SortColumn VARCHAR(50),
@SortDirection CHAR(3),
@Results INT OUTPUT

--Statements--
SELECT @Results = COUNT(ID) FROM Customers
WHERE FirstName LIKE '%a%'

SET @StartIndex = @StartIndex - 1 --Either do this here or in code, but be consistent
CREATE TABLE #Page(ROW INT IDENTITY(1,1) NOT NULL, id INT, sorting_1 SQL_VARIANT, sorting_2 SQL_VARIANT)
INSERT IGNORE  INTO #Page(ID, sorting_1, sorting_2)
SELECT TOP (@StartIndex + @PageSize)
    ID,
    CASE
        WHEN @SortColumn='FirstName' AND @SortDirection='ASC' THEN CAST(FirstName AS SQL_VARIANT)
        WHEN @SortColumn='LastName' AND @SortDirection='ASC' THEN CAST(LastName AS SQL_VARIANT)
        ELSE NULL
    END AS sort_1,
    CASE
        WHEN @SortColumn='FirstName' AND @SortDirection='DES' THEN CAST(FirstName AS SQL_VARIANT)
        WHEN @SortColumn='LastName' AND @SortDirection='DES' THEN CAST(LastName AS SQL_VARIANT)
        ELSE NULL
    END AS sort_2
FROM (
    SELECT
        CustomerId AS ID,
        FirstName,
        LastName
    FROM Customers
    WHERE
        FirstName LIKE '%a%'
) C
ORDER BY sort_1 ASC, sort_2 DESC, ID ASC;

SELECT
    ID,
    Customers.FirstName,
    Customers.LastName
FROM #Page
INNER JOIN Customers ON
    ID = Customers.CustomerId
WHERE ROW > @StartIndex AND ROW <= (@StartIndex + @PageSize)
ORDER BY ROW ASC

DROP TABLE #Page
Respondida el 16/09/2008 a las 17:17
fuente por usuario

votos
0

Esto es lo que hago para paginar: todas mis grandes consultas que necesitan ser paginadas se codifican como inserciones en una tabla temporal. La tabla temporal tiene un campo de identidad que actuará de manera similar al row_number () mencionado anteriormente. Guardo el número de filas en la tabla temporal en un parámetro de salida para que el código de llamada sepa cuántos registros totales hay. El código de llamada también especifica qué página quiere y cuántas filas por página, que se seleccionan de la tabla temporal.

Lo bueno de hacerlo de esta manera es que también tengo un enlace "Exportar" que te permite obtener todas las filas del informe devuelto como CSV por encima de cada cuadrícula en mi aplicación. Este enlace utiliza el mismo procedimiento almacenado: simplemente devuelve el contenido de la tabla temporal en lugar de hacer la lógica de búsqueda. Esto tranquiliza a los usuarios que odian la búsqueda y quieren ver todo , y desean ordenarlo de millones de maneras diferentes.

Respondida el 13/08/2008 a las 15:16
fuente por usuario

votos
0

Creo que tendrías que realizar una consulta por separado para lograr eso desafortunadamente.

Pude lograr esto en mi posición anterior con ayuda de esta página: Paginación en DotNet 2.0

También lo tienen tirando un conteo de filas por separado.

Respondida el 05/08/2008 a las 22:05
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more