2010-02-11 48 views

回答

34

你可以尝试像

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

我觉得这个代码不到风度工作。你测试了这个代码吗? (它应该用“@Table”替换“PageNumbers”表) – RockOnGom 2013-03-20 02:21:06

+0

@zeitgeist,它使用了一个名为PageNumbers的CTE,你测试过的代码是不是? – 2013-03-20 04:35:10

33

您可以使用ROW_NUMBER()

返回结果集的分区内的行的顺序号,从1开始每个分区中的第一行。

例子:

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)CREATE伪数据

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)现在应用解。

这种情况下,假设EMPID是唯一的并且排序的列。

关 - 当然,你会运用它的不同列...

DECLARE @pageSize INT = 20 

SELECT * FROM (

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

WHERE MyQuery.PageNumber = 1   
+0

可爱的接近,但增加一个新的列可能是一个开销 – 2014-02-17 20:26:40

12

SQL Server 2012中提供了分页功能(见http://www.codeproject.com/Articles/442503/New-features-for-database-developers-in-SQL-Server

在SQL2008,你可以这样来做:

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!它的工作原理和规模一致。

0

这些是我在SQL服务器端分页查询结果的解决方案。我已经添加了过滤和排序的概念与一列。当您在GridView中进行分页和过滤时,它非常高效。在测试之前,你必须创建一个样本表并在该表中插入一行:(在现实世界中,你必须改变Where子句考虑你的表字段,也许你在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 

在SQL Server 2008中,您可以使用CTE概念。正因为如此,我已经写了两个类型的查询的SQL Server 2008+

- 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. 

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 

而第二个解决方案与CTE在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 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 

ON 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

请不要只发布一些代码,但请解释*为什么*和*代码如何解决此问题。 – 2017-01-30 08:03:37