I would like to get the 20 last entries of my table but order by ascending id.
In Sql it's not very complicated:
SELECT *
FROM (SELECT * FROM comments
WHERE postID='$id'
ORDER BY id DESC
LIMIT 20) t
ORDER BY id ASC;
But I would like to to it with my yii model like:
Comment::model()->findAll($criteria)
But i really don't know what I should put in my CDbCriteria!
$models = Comment::model()->findAll(array(
"condition" => "WHERE postID = '".$id."'",
"order" => "id DESC",
"limit" => 20,
));
Will get the last 20. And now you want to order that record set by id ASC correct? Is there not another field you can order by for a similar result (maybe a date or created field?) eg:
"order" => "id DESC, created ASC"
Scrap that secondary ordering, but why not just use array reverse?
$models = array_reverse($models);
There is a way without using array_reverse, if you think of using this sql:
SELECT * FROM `comments` `t`
WHERE id
in (SELECT id
FROM (SELECT id FROM comments Where postID = xyz ORDER BY id DESC LIMIT 20)
as q)
ORDER BY id ASC
which in criteria will become:
$criteria=new CDbCriteria();
$criteria->condition='id in (SELECT id FROM (SELECT id FROM comments Where postID='.$id.' ORDER BY id DESC LIMIT 20) as q)';
$criteria->order='id ASC';
Update:
With your original query, you could have also used findBySql :
$sql='SELECT * FROM (SELECT * FROM comments WHERE postID= :postid ORDER BY id DESC LIMIT 20) q ORDER BY id ASC';
$params=array('postid'=>$id);
$comments=Comment::model()->findAllBySql($sql,$params);
The performance of this query was better than my previous query.
UPD:
Please note, that in general, some other solutions are better than mine.
Using offset can decrease performance of your queries.
See: http://www.slideshare.net/Eweaver/efficient-pagination-using-mysql and Why does MYSQL higher LIMIT offset slow the query down?
So, when the number of Comments will increase, you can get performance degradation.
What about using offset feature?
$model = Comment::model();
$condition = 'postID =' . $id;
$limit = 20;
$totalItems = $model->count($condition);
$criteria = new CDbCriteria(array(
'condition' => $condition,
'order' => 'id ASC',
'limit' => $limit,
'offset' => $totalItems - $limit // if offset less, thah 0 - it starts from the beginning
));
$result = $model->findAll($criteria);
Related
I have this query:
select * from orders where week_of_year = '40' and user_id = '8631' and charge_date like in ('2017%','2018%') order by id desc limit 1
I have a syntax error near charge_date, I know the error I'm guessing I can't use like with 'in', is there anyway I can do the same logic that would actually work?
I guess, you need only year from the date and you want to search for multiple possible years.
Then your solution should look like below:
select * from orders where week_of_year = '40' and user_id = '8631' and YEAR(charge_date) REGEXP '2017|2018' order by id desc limit 1
Update:
Alternative Solution with IN
select * from orders where week_of_year = '40' and user_id = '8631' and YEAR(charge_date) IN (2017, 2018) order by id desc limit 1
I have this line:
$query = mysql_query("SELECT * FROM livechat WHERE type='public' ORDER BY id ASC LIMIT 15") ;
And this is for chat, however ASC takes only first ID comments, so it shows only 15 old comments (id1, id2 and so on). If I use DESC instead of ASC, it shows new comments, but in a bad way - newest at the top, since this is a chat, newest comments must be at the bottom.
Try creating a temporary table that contains the last 15 results, and then ordering from that table.
select * from (
select * from livechat where type='public' order by id desc limit 15
) tmp order by tmp.id asc
try like this:
$query = mysql_query("SELECT *
FROM (
SELECT *
FROM livechat
WHERE type='public'
ORDER BY id DESC LIMIT 15
) t
order by t.id") ;
So, I've written a query which should grab 15 most recent results from the 'messages' table, but order results by date in descending direction. My current query is as follows:
SELECT * FROM messages
WHERE chatID = 1
ORDER BY ID DESC, timeSent ASC
LIMIT 15
As you can see, I am using the 'ID DESC' to get the 15 most recent results, but the 'timeSent ASC' isn't ordering the results in the order I wish.
How can I correct my query to achieve this?
First fetch the messages by ordering the ID then sort it according to timeSent. You can try this -
SELECT * FROM
(SELECT * FROM messages WHERE chatID = 1 ORDER BY ID DESC LIMIT 15) messages_ordered
ORDER BY timeSent ASC
i have a MySql table that consists of 2 basic things:
The id and a value.
To show that on my page, i need to select, for example, the last 100 rows on reversed order.
So imagine that someone is putting data on it:
Id, value
1, 10
2, 9
3, 21
4, 15
i need, to select the last "3" rows (LIMIT + ORDER Clause), but not like this: 4,3,2 but like this: 2,3,4.
I know how to do that on code, but maybe there is a simple solution for that on Mysql and i don`t know.
Thanks
My SQL Query is like this right now:
SELECT `Data`.`id`, `Data`.`log_id`, `Data`.`value`, `Data`.`created` FROM `control_panel`.`datas` AS `Data` WHERE `Data`.`id` > 1000 AND `Data`.`log_id` = (2) ORDER BY `Data`.`id` DESC LIMIT 100
You need to wrap the first ORDER BY in a subselect which will return a limited selection ordered in descending order, then you can order that result in the outer query in ascending order:
SELECT
a.*
FROM
(
SELECT id, value
FROM tbl
ORDER BY id DESC
LIMIT 3
) a
ORDER BY
a.id
One way to do this would be with a sub-select.
SELECT *
FROM (SELECT * FROM table_name ORDER BY id DESC LIMIT 3) tmp
ORDER BY id ASC
simply
SELECT t.*
(SELECT * FROM table_name
ORDER BY column_name DESC
LIMIT 0,3) t
ORDER BY t.column_name ASC
use DESC to descending order, ASC to increasing order
What's the best, and easiest way to do this? My query currently is:
SELECT *
FROM chat
WHERE (userID = $session AND toID = $friendID)
OR (userID = $friendID AND toID = $session)
ORDER BY id
LIMIT 10
This shows the first 10 rows though, not the last 10.
EDIT: I Want the last 10 rows (Which yes, DESC does this) However I want them to be returned in ASCENDING order.
to reverse the order (therefore get last 10 instead of first 10), use DESC instead of ASC
EDIT
Based on your comment:
SELECT * FROM (
SELECT *
FROM chat
WHERE (userID = $session AND toID = $friendID)
OR (userID = $friendID AND toID = $session)
ORDER BY id DESC
LIMIT 10
) AS `table` ORDER by id ASC
If you want the last 10 then just change ASC to DESC
SELECT *
FROM
chat
WHERE
(userID=$session AND toID=$friendID)
OR
(userID=$friendID AND toID=$session)
ORDER BY id
DESC
LIMIT 10
$con = mysqli_connect("localhost","my_user","my_password","my_db");
$limit = 10;
$query = "SELECT * FROM $table";
$resource = mysqli_query($con,$query);
$total_rows = mysqli_num_rows($resource);
$start = $total_rows-$limit;
$query_limit= $query." LIMIT $start,$limit";
First I have set the limit
$limit = 10;
then
$total_rows = mysqli_num_rows($resource);
Here I have taken total number of rows affected.
$start = $total_rows-$limit;
then substracted limit from number of rows to take starting record number
$query_limit= $query." LIMIT $start,$limit";
and then added limit to the query.
For more information about limit see this link
https://www.w3schools.com/php/php_mysql_select_limit.asp
First select the last 10 from the table, then re-order them in ascending order.
SELECT * FROM (SELECT * FROM table ORDER BY id DESC LIMIT 10) sub ORDER BY id ASC