Codeigniter limit and offset pagination not working in descending order - php

Pagination worked fine in ASC order but I just can't get it to work in DESC order.
I have 10 test videos in my database with ids from 1-10, in the first batch I want to get the last 5 videos (ids: 10,9,8,7,6) and in the next batch the remaining ones (id:5,4,3,2,1).
The problem is that I always get empty results when using DESC order, here is my code:
$limit = 5;
$this->db->select('*');
$this->db->from('participant_videos');
$this->db->order_by('id','DESC');
$this->db->limit($limit,$index); // currently index is 10
$query=$this->db->get();
$videos = $query->result_array(); // empty array
echo $this->db->last_query();
// QUERY: SELECT * FROM `participant_videos` ORDER BY `id` DESC LIMIT 10, 5
return [
'videos' => $videos,
'index' => empty($videos) ? 0 : $index - $limit,
];
First time the index is determined like this:
public function get_latest_video () {
$video = $this->db->select("*")->limit(1)->order_by('id',"DESC")->get("participant_videos")->row_array();
return !empty($video['id']) ? $video['id'] : null; // index (10)
}
This is my table structure and content:
== Table structure for table participant_videos
|------
|Column|Type|Null|Default
|------
|//**id**//|int(11)|No|
|participant_id|int(11)|No|
|video_url|varchar(255)|No|
|video_type|varchar(255)|No|video/mp4
== Dumping data for table participant_videos
|2|2|/uploads/2-6138aef5a0717.mp4|video/mp4
|3|3|/uploads/3-6138b09449800.mp4|video/mp4
|4|4|/uploads/4-6138b0c3b1965.mp4|video/mp4
|5|5|/uploads/5-6138b0efa7aa1.mp4|video/mp4
|6|6|/uploads/6-6138b10667680.mp4|video/mp4
|7|7|/uploads/7-6138b154084a4.mp4|video/mp4
|8|8|/uploads/8-6138b1779bee0.mp4|video/mp4
|9|9|/uploads/9-613b4bc1e1d58.mp4|video/mp4
|10|16|/uploads/16-613b57a76c696.mp4|video/mp4

It turns out that offset "switches" sides when in DESC order, so instead of using biggest id as offset:
SELECT * FROM participant_videos ORDER BY id DESC LIMIT 10, 5
I had to change my offset to 0 to start from the biggest id:
SELECT * FROM participant_videos ORDER BY id DESC LIMIT 0, 5
This way I would recive the last 5 videos.

Related

Fetching last 100 row from mysql not working | JSON fromat

I'm trying to fetch the last 100 row but only one row is being displayed as a result
here is my php code:
<?php
require_once("variables.php");
$db = new ezSQL_mysql($GLOBALS['database_username'],$GLOBALS['database_password'],$GLOBALS['database_database'],$GLOBALS['database_server']);
header('Content-Type: application/json');
echo "{\"office\":\"0\",\"dept\":{\"desk\":[";
$symbols = addslashes($_GET['symbols']);
$symbolsArr = explode(",", $symbols);
foreach($symbolsArr as $s) {
$last = $db->get_row("select * from data where name='$s' order by id desc limit 0,100");
$jsonArray = array('name' => $s,
'phone' => $last->phone,
'active' => $last->active);
echo json_encode($jsonArray);}
echo "]}}";
?>
UPDATE> based on recommendations below I have changed get_row to get_results but the code broken now and it's not displaying any error.
Read the documentation on the database class you are using (ezSQL):
----------------------------------------------------
Example 2
----------------------------------------------------
// Get one row from the database..
$user = $db->get_row("SELECT name,email FROM users WHERE id = 2");
echo $user->name;
echo $user->email;
You are issuing a statement that is specifically to fetch one single row.
What you want to use is get_results() method instead of get_row() method.
I re-read your question and see that you were doing limit 0,100 which returns 100 rows starting with 0 (first). i thought you were trying to cycle those rows but I can see you are actually trying to only get the last row... my bad, derp.. well here - you are reversed somewhat in your query - should be 100,1 as you want the 100th row and only 1 row.
$last = $db->get_row("select * from data where name='{$s}' order by id desc limit 100,1");
$jsonArray = array('name' => $s,
'phone' => $last->phone,
'active' => $last->active);
Since you are trying to get last 100 rows use following statement:
$last = $db->get_results("select * from data where name='$s' order by id desc limit 100");
instead of
$last = $db->get_row("select * from data where name='$s' order by id desc limit 0,100");
ezSql get_results is the method which you need to use for retrieving multiple results from database.

how to get a specific id within 5 rows in a paging query in Mysql

I have a function in php I use it for paging it is like this :
$query = "SELECT id,
FROM table
ORDER BY id ASC
LIMIT $offset,5";
this work fine but what I want is to get the page that contain id number let say 10 and with it the other 4 rows, I want it to return something like this:
7,8,9,10,11,12 -> if I give it id number 10.
25,26,27,28,29 -> if I give it id number 26 and so on.
like it would return the 5 rows but I want to know how to set the offset that will get me
the page that have the 5 rows with the specified id included.
what should I do like adding where clause or something to get what I want!
Notice that the IDs in your table won't be consecutive if you delete some rows. The code below should work in such conditions:
$result = mysql_query('select count(*) from table where id < ' . $someId);
$offset = mysql_result($result, 0, 0);
$result = mysql_query('select * from table order by id limit ' . max($offset - 2, 0) . ',5');
while ($row = mysql_fetch_assoc($result)) {
print_r($row);
}
Try something like this
//but for pagination to work $page should be $page*$limit, so new rows will come to your page
$limit = 5;
$start = ($page*limit) -2; // for normal pagination
$start = $page -2; // for your case, if you want ids around the $page value - in this case for id = 10 you will get 8 9 10 11 12
if ($start < 0) $start = 0; // for first page not to try and get negative values
$query = "SELECT id,
FROM rowa
ORDER BY id ASC
LIMIT $start,$limit";

How to create Show More Posts in PHP?

How to create that only first few posts from database are shown on a page, and after those posts you have Show More Posts button, and when you click it, it shows another few posts after the previous posts, and after that you again have Show More Posts button to show next few posts, until there is no more posts to show?
Something like Facebook have or YouTube with their comments.
If in table all_posts_table I have 2 columns: id and post,
this line of code will only show first 5 posts:
$posts = mysql_query("SELECT * FROM all_posts_table ORDER BY id LIMIT 5");
while ($line_posts = mysql_fetch_assoc($posts)) {
$post = $line_posts['post'];
echo $post."<br>";
}
You have to use OFFSET (or its short form: LIMIT x,y):
SELECT ... LIMIT 5 -- gives you the first 5 database entries
SELECT ... OFFSET 5 -- gives you all BUT the first 5 entries
SELECT ... LIMIT 5 OFFSET 10 -- gives you the 10 entries AFTER the first 5
SELECT ... LIMIT 5,10 -- that's the short form of LIMIT 5 OFFSET 10
You can use OFFSET together with LIMIT like this:
$offset = isset ($_GET['offset']) ? $_GET['offset'] : 0;
$posts = mysql_query("SELECT * FROM all_posts_table ORDER BY id LIMIT 5 OFFSET $offset");
while ($line_posts = mysql_fetch_assoc($posts)) {
$post = $line_posts['post'];
echo $post."<br>";
}
echo "<a href='" . $_SERVER ['REQUEST_URI'] . "?offset=".($offset + 5)."'>Next</a>";

Get total rows count of table

I want to get all rows count in my sql.
Table's first 2 columns look like that
My function looks like that
$limit=2;
$sql = "SELECT id,COUNT(*),dt,title,content FROM news ORDER BY dt DESC LIMIT " . $limit;
$stmt = $this->db->prepare($sql);
$stmt->execute();
$stmt->bind_result($id, $total, $datetime, $title, $content);
$stmt->store_result();
$count = $stmt->num_rows;
if ($count > 0) {
while ($stmt->fetch()) {
Inside loop, I'm getting exact value of $total, but MySQL selects only 1 row - row with id number 1. (and $count is 1 too)
Tried this sql
SELECT id,dt,title,content FROM news ORDER BY dt DESC LIMIT 2
All goes well.
Why in first case it selects only 1 row? How can I fix this issue?
for ex my table has 5 rows. I want to get 2 of them with all fields, and get all rows count (5 in this case) by one query.
Remove COUNT(*). You will only ever get 1 row if you leave it in there.
Try adding GROUP BY dt if you want to use COUNT(*) (not sure why you're using it though).
EDIT
Fine, if you insist on doing it in a single call, here:
$sql = "SELECT id,(SELECT COUNT(id) FROM news) as total,dt,title,content FROM news ORDER BY dt DESC LIMIT " . $limit;
This is likely cause by the variable $limit being set to 1, or not being set and mysql defaulting to 1. Try changing your first line to
$sql = "SELECT id,COUNT(*),dt,title,content FROM news ORDER BY dt DESC";
EDIT
Change to:
$sql = "SELECT SQL_CALC_FOUND_ROWS,id,dt,title,content FROM news ORDER BY dt DESC LIMIT " . $limit;
And then use a second query with
SELECT FOUND_ROWS( )
to get the number of rows that match the query
This totally wreaks of a HW problem... why else besides a professor's retarded method to add complexity to a simple problem would you not want to run two queries?
anyways.... here:
SELECT id, (SELECT COUNT(*) FROM news) AS row_count, dt, title, content FROM news ORDER BY dt DESC LIMIT

Query issue in Codeigniter

I want to random show 6 news/reviews on my front page but it shows the same content 6 times random but I will not have duplication of content. Here is the SQL query:
SELECT
anmeldelser.billed_sti ,
anmeldelser.overskrift ,
anmeldelser.indhold ,
anmeldelser.id ,
anmeldelser.godkendt
FROM
anmeldelser
LIMIT 0,6
UNION ALL
SELECT
nyheder.id ,
nyheder.billed_sti ,
nyheder.overskrift ,
nyheder.indhold ,
nyheder.godkendt
FROM nyheder
ORDER BY rand() LIMIT 0,6
showing my example with active record for simplicity,
try randomizing your offset instead of the order, while still limiting to 6
// get the total number of rows
$total_rows = $this->db->count_all_results('my_table');
// offset random point within the total rows
$offset = rand( 0 , $total_rows - 6 );
$q = $this->db->offset( $offset )->limit( 6 )->get( 'my_table' );
print_r( $q->result_array() );
//initialize query builder
$sql1=$sql2=$this->db;
$sql1->select('anmeldelser.billed_sti ,anmeldelser.overskrift ,anmeldelser.indhold ,anmeldelser.id ,anmeldelser.godkendt');
$sql1->from('anmeldelser');
$sql1->order_by('rand()');
$sql1->limit(3);
//get only sql string
$query1=$sql1->get_compiled_select();
$sql2->select('nyheder.id ,nyheder.billed_sti ,nyheder.overskrift ,nyheder.indhold ,nyheder.godkendt');
$sql2->from('nyheder');
$sql2->order_by('rand()');
$sql2->limit(3);
$query2=$sql2->get_compiled_select();
//combine two query
$query = $this->mydb->query("($query1) UNION ($query2)");
$result = $query->result();
I am assuming that you need to join a Two table by this comment of yours.
You didn't mention your foreign key so I am assuming that also.
It is also not clear that the column name of your tables are same or not.
So, I am posting an join query for your table in which I assume your foreign key and column name, so please correct that before using it.
Here is your query to join your table:
$query = $this->db
->select('an.billed_sti,an.overskrift,an.indhold,an.id,an.godkendt, ny.id as ny_id,ny.billed_sti as ny_billed_sti, ny.overskrift as ny_overskrift, ny.indhold as ny_indhold , ny.godkendt as ny_godkendt ')
->from('anmeldelser as an')
->join('nyheder as ny', 'ny.id_fk = an.id', 'left outer') // I am assuming here that the [id_fk] field is the foreign key
->limit(0, 6)
->order_by('puttablename.tablecolumn', 'asc') // Your you table name and column name by which you want to order, you can use [asc/desc] as your need
->get();
And If you want to UNION here is the solution for it.

Categories