Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pagination using MySQL LIMIT, OFFSET

I have some code that LIMITs data to display only 4 items per page. The column I'm using has about 20-30 items, so I need to make those spread out across the pages.

On the first page, I have:

    $result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4"); {   echo "<tr>";   echo "<td align='center'><img src=\"" . $row['picturepath'] . "\" /></td>";   echo "<td align='center'>" . $row['name'] . "</td> <td align='center'> <input type='button' value='More Info'; onclick=\"window.location='more_info.php?';\"> </td>";   echo "<td align='center'>" . $row['price'] . "</td> <td align='center'> <input type='button' value='Add to Order' onclick=''> </td>";   echo "</tr>";  } echo "</table>";  mysqli_close($con);      ?>       <table width="1024" align="center" >         <tr height="50"></tr>             <tr>                 <td width="80%" align="right">                     <a href="itempage2.php">NEXT</a>                 </td>                 <td width="20%" align="right">                     <a href="">MAIN MENU</a>                 </td>             </tr>     </table> 

You'll notice towards the bottom of the page my anchor tag within lists the second page, "itempage2.php". In item page 2, I have the same code, except my select statement lists the offset of 4.

$result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4 offset 4"); 

This works, this way when there is a pre-determined number of items within my database. But it's not that good. I need to create a new page only if there are more items, not hard-coded into it like it is now.

How can I create multiple pages without having to hard-code each new page, and offset?

like image 680
ValleyDigital Avatar asked Dec 04 '13 00:12

ValleyDigital


People also ask

How do you use limit and offset in pagination?

LIMIT n is an alternative syntax to the FETCH FIRST n ROWS ONLY. The OFFSET clause specifies the number of rows of the result table to skip before any rows are retrieved, and must be used with the LIMIT clause. The OFFSET clause instructs the server where to start returning rows within the query result.

How do you adjust offset in pagination?

Use offset = (page - 1) * itemsPerPage + 1 .

How does limit and offset work in MySQL?

MySQL Offset is used to specify from which row we want the data to retrieve. To be precise, specify which row to start retrieving from. Offset is used along with the LIMIT. Here, LIMIT is nothing but to restrict the number of rows from the output.

Does MySQL support pagination?

The pagination is a very interesting concept in MySQL and can be achieved easily by LIMIT and OFFSET clauses. It is very useful when you want to display the large recordset on multiple pages.


1 Answers

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>';    } } 
like image 124
Mike Brant Avatar answered Sep 28 '22 18:09

Mike Brant