如何在2008 R2的SQL查询中编写分页/限制?

时间:2014-05-13 21:50:33

标签: sql sql-server sql-server-2008

这是我的出发点:

SELECT * FROM crm_main t1
    INNER JOIN crm_group_relationships t2
        ON t1.id = t2.customerid
    OUTER APPLY (
            SELECT TOP 1 t3.timestamp, t3.customerid, t3.comments
            FROM crm_comments t3 
            WHERE t1.id = t3.customerid
            ORDER BY t3.timestamp ASC
        ) t3 
WHERE t1.dealerid = '9999' AND t2.groupid = '251'

我不明白为什么微软这样做如此困难。在MySQL中,您可以使用带有偏移量的LIMIT子句。

基本上我要做的就是加入3个表,其中一个表只需要拉一行(最新的评论可以按照记录中最后一个评论的最新时间戳排序)。我能够实现这一点,但现在我不得不尝试在查询中写入分页。

我正在使用SQL 2008 R2。

我看过这个: http://blog.sqlauthority.com/2013/04/14/sql-server-tricks-for-row-offset-and-paging-in-various-versions-of-sql-server/,但我无法理解这是如何运作的。

以下是基于以上链接的尝试:

DECLARE @RowsPerPage INT = 10
DECLARE @PageNumber INT = 6

SELECT * FROM (
SELECT *,ROW_NUMBER() OVER (ORDER BY id) AS RowNum FROM crm_main t1
    INNER JOIN crm_group_relationships t2
        ON t1.id = t2.customerid
    OUTER APPLY (
            SELECT TOP 1 t3.timestamp, t3.customerid, t3.comments
            FROM crm_comments t3 
            WHERE t1.id = t3.customerid
            ORDER BY t3.timestamp ASC
        ) t3 
WHERE t1.dealerid = '9999' AND t2.groupid = '251'
) AS SOD
WHERE SOD.RowNum BETWEEN ((@PageNumber - 1) * @RowsPerPage) + 1
        AND @RowsPerPage * (@PageNumber)

输出:

Msg 209, Level 16, State 1, Line 5
Ambiguous column name 'id'.
Msg 8156, Level 16, State 1, Line 16
The column 'id' was specified multiple times for 'SOD'.

1 个答案:

答案 0 :(得分:3)

由于您使用的是Server 2008,因此可以使用该链接中的这个优秀示例。 (格式化为更易读):

DECLARE @RowsPerPage INT = 10
DECLARE @PageNumber INT = 6

SELECT SalesOrderDetailID
    ,SalesOrderID
    ,ProductID
FROM (
    SELECT SalesOrderDetailID
        ,SalesOrderID
        ,ProductID
        ,ROW_NUMBER() OVER (
            ORDER BY SalesOrderDetailID
            ) AS RowNum
    FROM Sales.SalesOrderDetail
    ) AS SOD
WHERE SOD.RowNum BETWEEN ((@PageNumber - 1) * @RowsPerPage) + 1
        AND @RowsPerPage * (@PageNumber)

这将返回第六页,每页有十条记录。 ROW_NUMBER()基本上为此查询分配一个临时标识列,按SalesOrderDetailID排序。

然后,您可以为第六页选择行号在61-70之间的记录。

希望有意义


根据您的额外尝试工作:

DECLARE @RowsPerPage INT = 10
DECLARE @PageNumber INT = 6

SELECT *
FROM (
    SELECT t1.*
        ,t3.[timestamp]
        ,t3.comments
        ,ROW_NUMBER() OVER (
            ORDER BY t1.id
            ) AS RowNum
    FROM crm_main t1
    INNER JOIN crm_group_relationships t2 ON t1.id = t2.customerid
    OUTER APPLY (
        SELECT TOP 1 t3.[timestamp]
            ,t3.customerid
            ,t3.comments
        FROM crm_comments t3
        WHERE t1.id = t3.customerid
        ORDER BY t3.TIMESTAMP ASC
        ) t3
    WHERE t1.dealerid = '9999'
        AND t2.groupid = '251'
    ) AS x
WHERE x.RowNum BETWEEN ((@PageNumber - 1) * @RowsPerPage) + 1
        AND @RowsPerPage * (@PageNumber)