2010-02-11 16 views

Respuesta

34

Usted puede intentar algo como

DECLARE @Table TABLE(
     Val VARCHAR(50) 
) 

DECLARE @PageSize INT, 
     @Page INT 

SELECT @PageSize = 10, 
     @Page = 2 

;WITH PageNumbers AS(
     SELECT Val, 
       ROW_NUMBER() OVER(ORDER BY Val) ID 
     FROM @Table 
) 
SELECT * 
FROM PageNumbers 
WHERE ID BETWEEN ((@Page - 1) * @PageSize + 1) 
     AND (@Page * @PageSize) 
+0

creo que este código dosn't trabajo. ¿Has probado este código? (debe reemplazar la tabla "PageNumbers" con "@Table". – RockOnGom

+0

@zeitgeist, está haciendo uso de un CTE llamado PageNumbers. ¿Probé el código como está? –

33

Puede utilizar ROW_NUMBER():

Devuelve el número secuencial de una fila dentro de una partición de un conjunto de resultados, a partir de 1 para la primera fila de cada partición.

Ejemplo:

WITH CTEResults AS 
(
    SELECT IDColumn, SomeField, DateField, ROW_NUMBER() OVER (ORDER BY DateField) AS RowNum 
    FROM MyTable 
) 

SELECT * 
FROM CTEResults 
WHERE RowNum BETWEEN 10 AND 20; 
2

1) Crear DUMMY DATOS

CREATE TABLE #employee (EMPID INT IDENTITY, NAME VARCHAR(20)) 

DECLARE @id INT = 1 

WHILE @id < 200 

BEGIN 
INSERT INTO #employee (NAME) VALUES ('employee_' + CAST(@id AS VARCHAR)) 
SET @id = @id + 1 
END 

2) se aplican ahora la solución.

Este caso asume que EMPID es una columna única y ordenada.

fuera de curso, se le aplicará una columna diferente ...

DECLARE @pageSize INT = 20 

SELECT * FROM (

SELECT *, PageNumber = CEILING(CAST(EMPID AS FLOAT)/@pageSize) 
FROM #employee 
) MyQuery 

WHERE MyQuery.PageNumber = 1   
+0

Encantador enfoque, pero agregar una nueva columna podría ser una sobrecarga –

12

SQL Server 2012 proporciona la funcionalidad de paginación (véase http://www.codeproject.com/Articles/442503/New-features-for-database-developers-in-SQL-Server)

En SQL2008 que puede hacerlo de esta manera:

declare @rowsPerPage as bigint; 
declare @pageNum as bigint; 
set @rowsPerPage=25; 
set @pageNum=10; 

With SQLPaging As ( 
    Select Top(@rowsPerPage * @pageNum) ROW_NUMBER() OVER (ORDER BY ID asc) 
    as resultNum, * 
    FROM Employee) 
select * from SQLPaging with (nolock) where resultNum > ((@pageNum - 1) * @rowsPerPage) 

Prooven! Funciona y escala consistentemente.

0

Estas son mi solución para paginar el resultado de la consulta en el lado del servidor SQL. He agregado el concepto de filtrado y orden con una columna. Es muy eficiente cuando busca y filtra y ordena en su Gridview.

Antes de probar, debe crear una tabla de muestra e insertar una fila en esta tabla: (En el mundo real debe cambiar la cláusula Where considerando su campo de tabla y quizás tenga alguna combinación y subconsulta en la parte principal de select)

Create Table VLT 
(
    ID int IDentity(1,1), 
    Name nvarchar(50), 
    Tel Varchar(20) 
) 
GO 


Insert INTO VLT 
VALUES 
    ('NAME' + Convert(varchar(10),@@identity),'FAMIL' +  Convert(varchar(10),@@identity)) 
GO 500000 

En SQL server 2008, puede utilizar el concepto CTE.Debido a eso, he escrito dos tipos de consulta para el servidor SQL 2008+

- Servidor 2008+

DECLARE @PageNumber Int = 1200 
DECLARE @PageSize INT = 200 
DECLARE @SortByField int = 1 --The field used for sort by 
DECLARE @SortOrder nvarchar(255) = 'ASC' --ASC or DESC 
DECLARE @FilterType nvarchar(255) = 'None' --The filter type, as defined on the client side (None/Contain/NotContain/Match/NotMatch/True/False/) 
DECLARE @FilterValue nvarchar(255) = '' --The value the user gave for the filter 
DECLARE @FilterColumn int = 1 --The column to wich the filter is applied, represents the column number like when we send the information. 

SELECT 
    Data.ID, 
    Data.Name, 
    Data.Tel 
FROM 
    ( 
    SELECT 
     ROW_NUMBER() 
     OVER(ORDER BY 
       CASE WHEN @SortByField = 1 AND @SortOrder = 'ASC' 
         THEN VLT.ID END ASC, 
       CASE WHEN @SortByField = 1 AND @SortOrder = 'DESC' 
         THEN VLT.ID END DESC, 
       CASE WHEN @SortByField = 2 AND @SortOrder = 'ASC' 
         THEN VLT.Name END ASC, 
       CASE WHEN @SortByField = 2 AND @SortOrder = 'DESC' 
         THEN VLT.Name END ASC, 
       CASE WHEN @SortByField = 3 AND @SortOrder = 'ASC' 
         THEN VLT.Tel END ASC, 
       CASE WHEN @SortByField = 3 AND @SortOrder = 'DESC' 
         THEN VLT.Tel END ASC 
     ) AS RowNum 
     ,* 
    FROM VLT 
    WHERE 
     (-- We apply the filter logic here 
     CASE 
      WHEN @FilterType = 'None' THEN 1 

      -- Name column filter 
      WHEN @FilterType = 'Contain' AND @FilterColumn = 1 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.ID LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'NotContain' AND @FilterColumn = 1 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.ID NOT LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'Match' AND @FilterColumn = 1 
      AND VLT.ID = @FilterValue THEN 1 
      WHEN @FilterType = 'NotMatch' AND @FilterColumn = 1 
      AND VLT.ID <> @FilterValue THEN 1    

      -- Name column filter 
      WHEN @FilterType = 'Contain' AND @FilterColumn = 2 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.Name LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'NotContain' AND @FilterColumn = 2 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.Name NOT LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'Match' AND @FilterColumn = 2 
      AND VLT.Name = @FilterValue THEN 1 
      WHEN @FilterType = 'NotMatch' AND @FilterColumn = 2 
      AND VLT.Name <> @FilterValue THEN 1   

     -- Tel column filter 
     WHEN @FilterType = 'Contain' AND @FilterColumn = 3 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.Tel LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'NotContain' AND @FilterColumn = 3 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.Tel NOT LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'Match' AND @FilterColumn = 3 
      AND VLT.Tel = @FilterValue THEN 1 
      WHEN @FilterType = 'NotMatch' AND @FilterColumn = 3 
      AND VLT.Tel <> @FilterValue THEN 1  

     END 
    ) = 1 
) AS Data 
WHERE Data.RowNum > @PageSize * (@PageNumber - 1) 
    AND Data.RowNum <= @PageSize * @PageNumber 
ORDER BY Data.RowNum 

GO 

Y segunda solución SQL con CTE en el servidor SQL 2008+

DECLARE @PageNumber Int = 1200 
DECLARE @PageSize INT = 200 
DECLARE @SortByField int = 1 --The field used for sort by 
DECLARE @SortOrder nvarchar(255) = 'ASC' --ASC or DESC 
DECLARE @FilterType nvarchar(255) = 'None' --The filter type, as defined on the client side (None/Contain/NotContain/Match/NotMatch/True/False/) 
DECLARE @FilterValue nvarchar(255) = '' --The value the user gave for the filter 
DECLARE @FilterColumn int = 1 --The column to wich the filter is applied, represents the column number like when we send the information. 

;WITH 
    Data_CTE 
    AS 
    ( 
    SELECT 
     ROW_NUMBER() 
     OVER(ORDER BY 
       CASE WHEN @SortByField = 1 AND @SortOrder = 'ASC' 
         THEN VLT.ID END ASC, 
       CASE WHEN @SortByField = 1 AND @SortOrder = 'DESC' 
         THEN VLT.ID END DESC, 
       CASE WHEN @SortByField = 2 AND @SortOrder = 'ASC' 
         THEN VLT.Name END ASC, 
       CASE WHEN @SortByField = 2 AND @SortOrder = 'DESC' 
         THEN VLT.Name END ASC, 
       CASE WHEN @SortByField = 3 AND @SortOrder = 'ASC' 
         THEN VLT.Tel END ASC, 
       CASE WHEN @SortByField = 3 AND @SortOrder = 'DESC' 
         THEN VLT.Tel END ASC 
     ) AS RowNum 
     ,* 
    FROM VLT 
    WHERE 
     (-- We apply the filter logic here 
     CASE 
      WHEN @FilterType = 'None' THEN 1 

      -- Name column filter 
      WHEN @FilterType = 'Contain' AND @FilterColumn = 1 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.ID LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'NotContain' AND @FilterColumn = 1 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.ID NOT LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'Match' AND @FilterColumn = 1 
      AND VLT.ID = @FilterValue THEN 1 
      WHEN @FilterType = 'NotMatch' AND @FilterColumn = 1 
      AND VLT.ID <> @FilterValue THEN 1    

      -- Name column filter 
      WHEN @FilterType = 'Contain' AND @FilterColumn = 2 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.Name LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'NotContain' AND @FilterColumn = 2 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.Name NOT LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'Match' AND @FilterColumn = 2 
      AND VLT.Name = @FilterValue THEN 1 
      WHEN @FilterType = 'NotMatch' AND @FilterColumn = 2 
      AND VLT.Name <> @FilterValue THEN 1   

     -- Tel column filter 
     WHEN @FilterType = 'Contain' AND @FilterColumn = 3 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.Tel LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'NotContain' AND @FilterColumn = 3 
      AND (-- In this case, when the filter value is empty, we want to show everything. 
       VLT.Tel NOT LIKE '%' + @FilterValue + '%' 
       OR 
       @FilterValue = '' 
       ) THEN 1 
      WHEN @FilterType = 'Match' AND @FilterColumn = 3 
      AND VLT.Tel = @FilterValue THEN 1 
      WHEN @FilterType = 'NotMatch' AND @FilterColumn = 3 
      AND VLT.Tel <> @FilterValue THEN 1  

     END 
    ) = 1  
) 

SELECT 
    Data.ID, 
    Data.Name, 
    Data.Tel 
FROM Data_CTE AS Data 
WHERE Data.RowNum > @PageSize * (@PageNumber - 1) 
    AND Data.RowNum <= @PageSize * @PageNumber 
ORDER BY Data.RowNum 
-2

SELECT ID DISTINCT, ParticipantId, ActivityDate, IsApproved, IsDeclined, IsDeleted, SubmissionDate, IsResubmitted,

[CategoryId] Id,[CategoryName] Name, 

    [ActivityId] [Id],[ActivityName] Name,Points, 

    [UserId] [Id],Email, 
    ROW_NUMBER() OVER(ORDER BY Id desc) AS RowNum from 
    (SELECT DISTINCT 
    Id,ParticipantId, 
    ActivityDate,IsApproved, 
    IsDeclined,IsDeleted, 
    SubmissionDate, IsResubmitted, 

    [CategoryId] [CategoryId],[CategoryName] [CategoryName], 

    [ActivityId] [ActivityId],[ActivityName] [ActivityName],Points, 

    [UserId] [UserId],Email, 
    ROW_NUMBER() OVER(ORDER BY Id desc) AS RowNum from 

    (SELECT DISTINCT ASN.Id, 
    ASN.ParticipantId,ASN.ActivityDate, 
    ASN.IsApproved,ASN.IsDeclined, 
    ASN.IsDeleted,ASN.SubmissionDate, 
    CASE WHEN (SELECT COUNT(*) FROM FDS_ActivitySubmission WHERE ParentId=ASN.Id)>0 THEN CONVERT(BIT, 1) ELSE CONVERT(BIT, 0) END IsResubmitted, 

    AC.Id [CategoryId], AC.Name [CategoryName], 

    A.Id [ActivityId],A.Name [ActivityName],A.Points, 

    U.Id[UserId],U.Email  


FROM 
FDS_ActivitySubmission ASN WITH (NOLOCK) 
INNER JOIN 
    FDS_ActivityCategory AC WITH (NOLOCK) 
ON 
    AC.Id=ASN.ActivityCategoryId 
     INNER JOIN 
    FDS_ApproverDetails FDSA 
ON 
FDSA.ParticipantID=ASN.ParticipantID 

     INNER JOIN 
     FDS_ActivityJobRole FAJ 

EN FAJ.RoleId = FDSA.JobRoleId INNER JOIN

FDS_Activity A WITH (NOLOCK) 
ON 
    A.Id=ASN.ActivityId 
INNER JOIN 
    Users U WITH (NOLOCK) 
ON 
    ASN.ParticipantId=FDSA.ParticipantID 
WHERE 
     [email protected] AND [email protected] AND ASN.IsDeleted=0 
     AND 
     ISNULL(U.Id,0)=ISNULL(@ApproverId,0) 
     AND ISNULL(ASN.IsDeleted,0)<>1)P)t where t.RowNum between 
     (((@PageNumber - 1) * @PageSize) + 1) AND (@PageNumber * PageSize) 
    AND [email protected] AND [email protected] AND t.IsDeleted = 0 
AND (ISNULL(t.Id,0)=ISNULL(@SubmissionId,0)or ISNULL(@SubmissionId,0)<=0) 
+0

No solo publique código, pero explique * por qué * y * cómo * este código resuelve el problema. –