Recently I’ve faced weird issue. I have two simple queries where one of them uses TOP X and other one does the same by using ROW_NUMBER and then selects items with rowNumber between 1 and X, and both of them ordered by same column, but the result is completely different.
For example, let’s say we have a simple DB as below with some dummy data:
CREATE TABLE [dbo].[Test](
[Id] [int] IDENTITY(1,1) NOT NULL,
[NDate] [datetime] NOT NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
SET IDENTITY_INSERT [dbo].[Test] ON
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (1, '2011-08-24 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (2, '2011-08-24 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (3, '2011-08-24 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (4, '2011-08-24 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (5, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (6, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (7, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (8, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (9, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (10, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (11, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (12, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (13, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (14, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (15, '2011-08-21 00:00:00.000')
INSERT [dbo].[Test] ([Id], [NDate]) VALUES (16, '2011-08-21 00:00:00.000')
SET IDENTITY_INSERT [dbo].[Test] OFF
Now if we perform below queries, we will get different results. If we use TOP 10, we will get below result:
SELECT TOP 10 [Id],[NDate] FROM [Test] order by NDate desc
RESULT=>
Id NDate
4 2011-08-24 00:00:00.000
3 2011-08-24 00:00:00.000
2 2011-08-24 00:00:00.000
1 2011-08-24 00:00:00.000
11 2011-08-21 00:00:00.000
10 2011-08-21 00:00:00.000
9 2011-08-21 00:00:00.000
8 2011-08-21 00:00:00.000
7 2011-08-21 00:00:00.000
6 2011-08-21 00:00:00.000
select id,NDate from (
select ROW_NUMBER() over (order by NDate DESC) as RNumber, Id,NDate
from Test) as t
where RNumber between 1 and 10
RESULT=>
id NDate
1 2011-08-24 00:00:00.000
2 2011-08-24 00:00:00.000
3 2011-08-24 00:00:00.000
4 2011-08-24 00:00:00.000
5 2011-08-21 00:00:00.000
6 2011-08-21 00:00:00.000
7 2011-08-21 00:00:00.000
8 2011-08-21 00:00:00.000
9 2011-08-21 00:00:00.000
10 2011-08-21 00:00:00.000
The issue is, When you are using LINQ to SQL, and you want to do pagination, generated query for selecting first page will be TOP X, while for the other pages will be using ROW_NUMBER, and the result is, some items will never appear in the listing.
You need to implement a secondary sorting.
Example:
Example:
Otherwise, you might as well expect random records per unique
NDate.If you want the same records for each query, you have to specify that secondary sort column.