Divyang Desai
Divyang Desai

Reputation: 7866

Inner join gives undesired result with row number in sql server

I've tried to do a pagination on data in using ROW_NUMBER()
Here is my query:

SELECT * FROM
    (SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS Row,* FROM SpecificOrders) 
    AS EMP
        inner join Users as c on EMP.UserID = c.UserID
        inner join Users as u on EMP.CreatedBy = u.UserID       
        inner join SpecificOrderPayment as p on EMP.OrderID= p.OrderID

    WHERE Row BETWEEN 0 AND 10 

When I execute this query, I get output like following with :

Row | OrderID | UserID |
1   |         |        |
5   |         |        |
6   |         |        |
7   |         |        |
8   |         |        |
9   |         |        |
10  |         |        |

If I remove this WHERE Row BETWEEN 0 AND 10 condition then it'll gives me all records

Here my question is why I get only 7 rows and why here 2,3 and 4 is missing in the row column.

Moreover, If i remove 3rd join query (SpecificOrderPayment)then it will give me proper result.

Upvotes: 0

Views: 1137

Answers (2)

MtwStark
MtwStark

Reputation: 4058

The problem is that you are numbering the rows of SpecificOrders and not of final result.

In your case you only have one row per order, so using left joins should solve the issue

But, if the inner query could return multiple rows for each OrderID you will see the same row number many times

And if the join (inner) will filter some row you will not get that row number in result.

You have simply to separate the query for data extraction from the query for pagination,

Try this:

SELECT * 
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY EMP.OrderID) AS Row, EMP.*
    FROM SpecificOrders AS EMP
    left join Users as c on EMP.UserID = c.UserID
    left join Users as u on EMP.CreatedBy = u.UserID       
    left join SpecificOrderPayment as p on EMP.OrderID= p.OrderID
) D
WHERE [Row] BETWEEN 0 AND 10 

Upvotes: 2

Cato
Cato

Reputation: 3701

you've got OrderID that are null or blanks in SpecificOrders and they are sorting to the top - the approach isn't wrong otherwise, although there are other ways of doing it such as TOP 10..etc

SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS Row,* FROM SpecificOrders 
                                                  WHERE RTRIM(COALESCE(OrderID, '')) <> '') 
AS EMP
    inner join Users as c on EMP.UserID = c.UserID
    inner join Users as u on EMP.CreatedBy = u.UserID       
    inner join SpecificOrderPayment as p on EMP.OrderID= p.OrderID

WHERE Row BETWEEN 0 AND 10 

Upvotes: 2

Related Questions