Недавно я столкнулся со странной проблемой.У меня есть два простых запроса, где один из них использует TOP X, а другой делает то же самое, используя ROW_NUMBER, а затем выбирает элементы с rowNumber от 1 до X, и оба они упорядочены по одному столбцу, но результат совершенно другой.
Например, скажем, у нас есть простая БД, как показано ниже, с некоторыми фиктивными данными:
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
Теперь, если мы выполним запросы ниже, мы получим разные результаты.Если мы используем TOP 10, мы получим следующий результат:
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
Проблема в том, что когда вы используете LINQ to SQL и хотите выполнить разбиение на страницы, сгенерированный запрос для выбора первой страницы будет TOP Xв то время как для других страниц будет использоваться ROW_NUMBER, и в результате некоторые элементы никогда не появятся в списке.