Domanda

Here is my starting point:

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'

I don't understand why Microsoft made this so effing difficult. In MySQL you can just use the LIMIT clause with an offset.

Basically what I'm trying to do is join 3 tables, one of which has to pull only one row (the most recent comment to be able sort by the latest timestamp of the last comment on record). I was able to achieve this but now I'm stuck at trying to write paging into the query.

I'm using SQL 2008 R2.

I've looked at this: http://blog.sqlauthority.com/2013/04/14/sql-server-tricks-for-row-offset-and-paging-in-various-versions-of-sql-server/, but I can't wrap my mind around how this works.

Here is my attempt based on the above link:

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)

Output:

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'.
È stato utile?

Soluzione

Since you're using Server 2008, you can use this excellent example from that link. (formatted to be more readable):

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)

This will return the sixth page, of ten records on each page. ROW_NUMBER() basically assigns a temporary Identity column for this query, ordered by SalesOrderDetailID.

You can then select records where row number is between 61-70, for that sixth page.

Hope that makes sense


Working from your added attempt:

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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top