MS SQL服务器分页

时间:2018-07-04 12:09:05

标签: sql sql-server

我做了一个查询:

SELECT DISTINCT m.logID 
FROM Monitor_data m 
inner join Monitor_object o on (o.objID = m.domainID)
inner join Monitor_event e on (e.mainID = m.logID)
WHERE (o.name = @objName
and m.service = @service
and e.statement = @statement
and m.start >= @start
and m.end <= @end)

这使我可以获得一些id(VARCHAR(50))。但是,现在我想进行分页,因此需要修改该查询。不幸的是,我不能使用LIMIT和OFFSET ...我可以使用ROW_NUMBER,但我不知道如何:/最好得到与第n到m行对应的结果。这样,我将能够轻松创建分页过程。

有人可以帮助我吗? 谢谢。

5 个答案:

答案 0 :(得分:2)

尝试此查询:

select logID from (
    SELECT DISTINCT m.logID,
                    ROW_NUMBER() over (order by m.start) rn
    FROM Monitor_data m 
    inner join Monitor_object o on (o.objID = m.domainID)
    inner join Monitor_event e on (e.mainID = m.logID)
    WHERE (o.name = @objName
           and m.service = @service
           and e.statement = @statement
           and m.start >= @start
           and m.end <= @end)
) a where rn between (m, n) --here you provide values for limits for rows to return

以上查询基于SQL Server中的ROW_NUMBER函数,该函数需要进行一些排序,因此我假设m.start将提供一个命令(我认为它是开始日期或其他内容:))。

答案 1 :(得分:2)

使用@PageIndexPageSize进行分页

declare @PageIndex int=1
declare @PageSize int=10
declare @RecordCount int
SET NOCOUNT ON;
SELECT 
    ROW_NUMBER() OVER (ORDER BY m.logID ) as RowNumber, DISTINCT m.logID 
INTO #Results
FROM Monitor_data m 
    inner join Monitor_object o on (o.objID = m.domainID)
    inner join Monitor_event e on (e.mainID = m.logID)
WHERE (o.name = @objName
    and m.service = @service
    and e.statement = @statement
    and m.start >= @start
    and m.end <= @end)

SELECT @RecordCount = COUNT(*) FROM #Results

SELECT 
    *, @RecordCount as RecordCount  FROM #Results 
WHERE  
        RowNumber BETWEEN (@PageIndex -1) * @PageSize + 1 AND (((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1

DROP TABLE #Results

答案 2 :(得分:1)

我想这就是你想要的。

Select logId from 
(SELECT DISTINCT m.logID, Row_number() over (order by (select null)) as ranking 
FROM Monitor_data m 
inner join Monitor_object o on (o.objID = m.domainID)
inner join Monitor_event e on (e.mainID = m.logID)
WHERE (o.name = @objName
and m.service = @service
and e.statement = @statement
and m.start >= @start
and m.end <= @end))
where ranking between n and m

答案 3 :(得分:1)

按******订购

OFFSET @ItemsPerPage *(@CurrentPage-1)行

仅次于@ItemsPerPage ROWS

DECLARE @CurrentPage int = 1;
DECLARE @ItemsPerPage int = 10;

SELECT DISTINCT m.logID 
FROM Monitor_data m 
inner join Monitor_object o on (o.objID = m.domainID)
inner join Monitor_event e on (e.mainID = m.logID)
WHERE (o.name = @objName
and m.service = @service
and e.statement = @statement
and m.start >= @start
and m.end <= @end)


ORDER BY m.logID

OFFSET @ItemsPerPage * (@CurrentPage - 1) ROWS
FETCH NEXT @ItemsPerPage ROWS ONLY

分页示例

DECLARE @myTable TABLE(Id int, Name nvarchar(50),EventDate date);

INSERT INTO @myTable(Id, Name, EventDate)
VALUES (1, 'a', '2018-01-01'),
(2, 'b', '2018-01-02'),
(3, 'c', '2018-01-03'),
(4, 'd', '2018-01-04'),
(5, 'e', '2018-01-05'),
(6, 'f', '2018-01-06');


DECLARE @CurrentPage int = 1;
DECLARE @ItemsPerPage int = 4;


SELECT * FROM @myTable
ORDER BY EventDate  DESC
OFFSET @ItemsPerPage * (@CurrentPage - 1) ROWS
FETCH NEXT @ItemsPerPage ROWS ONLY

答案 4 :(得分:0)

从2012年开始,您可以使用OFFSET和FETCH。在此之前,解决方案是使用ROW_NUMBER。但是,请注意,ROW_NUMBER()方法非常慢。如果您没有性能问题,可以使用它。

无论什么版本,都使用TOP N进行快速分页,并按所需的列进行排序,并指定最小值。即:

select TOP (@pageSize) * from myTable
where myKeyValue > @minValue
order by myKeyValue;