Reputation: 539
I have this table definition
CREATE TABLE [dbo].[Earnings](
[Name] [nvarchar](50) NOT NULL,
[Date] [datetime] NOT NULL,
[Earnings] [decimal](18, 2) NOT NULL
)
I have this sample data
INSERT INTO [dbo].[Earnings] ([name], [Date], [Earnings])
VALUES
('person1', datefromparts(2015, 9, 1), 9.01),
('person1', datefromparts(2015, 10, 5), 10.05),
('person1', datefromparts(2015, 11, 21), 11.21),
('person1', datefromparts(2016, 1, 11), 1.12),
('person1', datefromparts(2016, 3, 13), 3.13),
('person1', datefromparts(2016, 5, 15), 5.15),
('person2', datefromparts(2016, 6, 16), 6.16),
('person2', datefromparts(2016, 8, 18), 8.18)
When I do pagination I always get same result for the following two sql statements, I would like to know what is the reason for this issue ? and what possible ways to fix it ?
SELECT * FROM [dbo].Earnings order by Name OFFSET 0 ROWS FETCH NEXT 2 ROWS ONLY ;
SELECT * FROM [dbo].Earnings order by Name OFFSET 2 ROWS FETCH NEXT 2 ROWS ONLY ;
The result I get for both execution
Name Date Earnings
person1 2015-11-21 00:00:00.000 11.21
person1 2015-10-05 00:00:00.000 10.05
Upvotes: 3
Views: 160
Reputation: 28890
Order by should be deterministic .which means if any column contains same value and is used in order by clause,sql will pick/can pick any row.so to make order by deterministic ,order by columns should be unique.
In your case ,use
SELECT * FROM [dbo].Earnings order by Name,date OFFSET 0 ROWS FETCH NEXT 2 ROWS ONLY ;
SELECT * FROM [dbo].Earnings order by Name,date OFFSET 2 ROWS FETCH NEXT 2 ROWS ONLY ;
Upvotes: 5
Reputation: 23078
Provided answer is correct. However, my suggestion is to add a PrimaryKey to your table and use that:
CREATE TABLE [dbo].[Earnings](
EarningId INT NOT NULL CONSTRAINT PK_Earnings PRIMARY KEY, -- can also be added IDENTITY(1, 1)
[Name] [nvarchar](50) NOT NULL,
[Date] [datetime] NOT NULL,
[Earnings] [decimal](18, 2) NOT NULL
)
The query becomes simple and I think also faster, as ordering will be done based on a clustered index:
SELECT * FROM [dbo].Earnings order by EarningId OFFSET 0 ROWS FETCH NEXT 2 ROWS ONLY;
SELECT * FROM [dbo].Earnings order by EarningId OFFSET 2 ROWS FETCH NEXT 2 ROWS ONLY;
Adding a PK
also has the main advantage that each record is clearly identifiable.
As a note, before ordering by a column, I have also noticed that ordering by SELECT 1
seems to do the trick:
SELECT * FROM [dbo].Earnings order by (SELECT 1) OFFSET 0 ROWS FETCH NEXT 2 ROWS ONLY;
SELECT * FROM [dbo].Earnings order by (SELECT 1) EarningId OFFSET 2 ROWS FETCH NEXT 2 ROWS ONLY;
However, I would not rely on this ordering.
Upvotes: 2