Pagination Using MySQL Limit, Offset

Pagination using MySQL LIMIT, OFFSET

First off, don't have a separate server script for each page, that is just madness. Most applications implement pagination via use of a pagination parameter in the URL. Something like:

http://yoursite.com/itempage.php?page=2

You can access the requested page number via $_GET['page'].

This makes your SQL formulation really easy:

// determine page number from $_GET
$page = 1;
if(!empty($_GET['page'])) {
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
if(false === $page) {
$page = 1;
}
}

// set the number of items to display per page
$items_per_page = 4;

// build query
$offset = ($page - 1) * $items_per_page;
$sql = "SELECT * FROM menuitem LIMIT " . $offset . "," . $items_per_page;

So for example if input here was page=2, with 4 rows per page, your query would be:

SELECT * FROM menuitem LIMIT 4,4

So that is the basic problem of pagination. Now, you have the added requirement that you want to understand the total number of pages (so that you can determine if "NEXT PAGE" should be shown or if you wanted to allow direct access to page X via a link).

In order to do this, you must understand the number of rows in the table.

You can simply do this with a DB call before trying to return your actual limited record set (I say BEFORE since you obviously want to validate that the requested page exists).

This is actually quite simple:

$sql = "SELECT your_primary_key_field FROM menuitem";
$result = mysqli_query($con, $sql);
$row_count = mysqli_num_rows($result);
// free the result set as you don't need it anymore
mysqli_free_result($result);

$page_count = 0;
if (0 === $row_count) {
// maybe show some error since there is nothing in your table
} else {
// determine page_count
$page_count = (int)ceil($row_count / $items_per_page);
// double check that request page is in range
if($page > $page_count) {
// error to user, maybe set page to 1
$page = 1;
}
}

// make your LIMIT query here as shown above


// later when outputting page, you can simply work with $page and $page_count to output links
// for example
for ($i = 1; $i <= $page_count; $i++) {
if ($i === $page) { // this is current page
echo 'Page ' . $i . '<br>';
} else { // show link to other page
echo '<a href="/menuitem.php?page=' . $i . '">Page ' . $i . '</a><br>';
}
}

Implementing pagination with mysql (limit and offset)

Full marks to the question preparation,

If I see the problem and understood correct, the issue is with the order you place limit and offset

There are two ways,

Either you explicitly mention the limit and offset as,

SELECT ISBN,AUTHOR_FIRST_NAME,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID 
FROM ASSESSMENT
ORDER BY ISBN ASC LIMIT 1 OFFSET 0;

OR

Incase you don't want to mention the word offset explicitly we need to pass the offset value first and then limit value as

SELECT ISBN,AUTHOR_FIRST_NAME,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID 
FROM ASSESSMENT
ORDER BY ISBN ASC LIMIT 0,1;

P.S. I didn't test each and individual cases as you mentioned but I think if my understanding correct you know what to do now.

when using limit and offset in mysql for pagination, how can I tell this is last page or not?

A trick I have used before is to get 1 more result than you need and just use it to determine if there is more. You will not know the last page's offset but you will know if the current offset is the last page.

For example if your page_count is something like 10 results then send a limit of 11. Then if you get 10 or less results you know this is the last page but if you get 11 you know there is another page and you show 10 and throw away the 11th result.

Python PSUEDO code

def get_page_of_results(current_offset, PAGE_COUNT=10):
results = session.query(Result).offset(current_offset).limit(PAGE_COUNT + 1).all()
return dict(
is_first=current_offset == 0,
is_last=len(results) < PAGE_COUNT,
next_offset=current_offset + PAGE_COUNT,
# Trim off last result
results=results[:PAGE_COUNT])

The performance between 10 and 11 shouldn't be a big deal unless you are loading huge object trees or something.

Also this method is db agnostic.

Use LIMIT to paginate results in MySQL query

MySQL requires numeric constants for that LIMIT syntax.

From http://dev.mysql.com/doc/refman/5.7/en/select.html:

The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants, with these exceptions:

  • Within prepared statements, LIMIT parameters can be specified using ? placeholder markers.

  • Within stored programs, LIMIT parameters can be specified using integer-valued routine parameters or local variables.

Compute the constant on the Java side.

MySQL Data - Best way to implement paging?

From the MySQL documentation:

The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants (except when using prepared statements).

With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):

SELECT * FROM tbl LIMIT 5,10;  # Retrieve rows 6-15

To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter. This statement retrieves all rows from the 96th row to the last:

SELECT * FROM tbl LIMIT 95,18446744073709551615;

With one argument, the value specifies the number of rows to return from the beginning of the result set:

SELECT * FROM tbl LIMIT 5;     # Retrieve first 5 rows

In other words, LIMIT row_count is equivalent to LIMIT 0, row_count.



Related Topics



Leave a reply



Submit