OFFSET

So, we know how to get the 5 most expensive cars in the cars table.

SELECT *
FROM cars
ORDER BY asking_price_usd DESC, miles_driven
LIMIT 5;
id
INTEGER
make
VARCHAR
model
VARCHAR
year
INTEGER
color
VARCHAR
asking_price_usd
INTEGER
miles_driven
NUMERIC
is_paid_off
BOOL
85027
honda
accord
2022
white
15990
300.0
FALSE
10128
acura
mdx
2010
black
9800
97000.0
TRUE
63278
infiniti
g37x
2009
black
8500
116000.0
TRUE
82330
hyundai
tucson
2010
white
7995
105749.2
TRUE
85215
mercedes-benz
c-class
2010
black
7250
165074.4
FALSE

How would be get the next 5 after that (the 5th through 10th most expensive). We could change it to LIMIT 10 and just look at the bottom 5. That would work, but sometimes we need to fetch rows in increments.

You've probably seen websites that show results in pages. When you finish 1 page, you click a button to go to the next page where more results are loaded.

Suppose each page has 5 cars. If you wanted to implement something like that, you could start with LIMIT 5, wait for the user to go to the next page, then repeat the query but with LIMIT 10, then LIMIT 15 etc. However, this is wasteful. Your database and your server are doing duplicate re-fetching previous pages. Instead, you can use OFFSET.

SELECT *
FROM cars
ORDER BY asking_price_usd DESC, miles_driven
LIMIT 5
OFFSET 5;
id
INTEGER
make
VARCHAR
model
VARCHAR
year
INTEGER
color
VARCHAR
asking_price_usd
INTEGER
miles_driven
NUMERIC
is_paid_off
BOOL
77029
lexus
es
2003
silver
6950
84591.3
TRUE
38935
honda
civic
2014
black
6900
80716.6
FALSE
31239
honda
civic
2007
black
6500
134000.0
TRUE
84470
honda
civic
2006
white
6250
6000.0
TRUE
50726
chevrolet
cruze
2014
blue
6000
102000.0
TRUE

While LIMIT defines the number of rows in the result, OFFSET says how many should be skipped from the top. Because we have ORDER BY asking_price_usd DESC, the effect off OFFSET 5 is to skip 1st 5 most expensive cars. The results will contain the 6th through 10th most expensive.

When we need the 3rd page…

SELECT *
FROM cars
ORDER BY asking_price_usd DESC, miles_driven
LIMIT 5
OFFSET 10;
id
INTEGER
make
VARCHAR
model
VARCHAR
year
INTEGER
color
VARCHAR
asking_price_usd
INTEGER
miles_driven
NUMERIC
is_paid_off
BOOL
92127
nissan
sentra
2016
black
6000
110000.0
TRUE
48069
hyundai
tucson
2010
blue
6000
124749.8
TRUE
20546
honda
accord
2008
blue
6000
141000.0
TRUE
90175
hyundai
elantra
2012
gray
5600
112000.0
TRUE
50708
nissan
altima
2010
gray
4800
100000.0
TRUE

© 2022 Andrew Carlson. All rights reserved.