CakePHP SQL conversion - basic ORDER BY - php

I have a table where I'd like to get all id's that equal 26 first, then have the rest sorted in descending order, so something like:
row id
--- --
1 26
2 26
3 26
4 27
5 25
6 24
Would normally result in:
select id
from table
order by id=26 desc, id desc
How should I construct a find() in Cake? This is what I figure:
$this->Model->find('all', array(
'conditions' => array('Model.id' => 26),
'order' => array('Model.id' => 'DESC')
));
But how should I tell Cake to retrieve the rest of the id's and sort them in descending order after retrieving all id's that equal 26?

Try this.
$this->Model->find('all', array(
'order' => array('Model.id = 26 DESC' , 'Model.id DESC')
));

Assuming that your id field is your primaryKey as defined by the CakePHP conventions, the query you have will only ever return one result. Thus the ordering is not relevant here.
I would also suggest using find('first') to prevent you getting a single result indexed numerically.
$this->Model->find('first', array('conditions' => array('id' => $id)));
If you wanted to return this single record, and then all the other records, I would inverse this with a find('all').
$this->Model->find('all', array('conditions' => array('id !=' => $id)));

Related

data escaping remove for specific filed in cakephp

I am using subquery for id field.
$db = $this->AccountRequest->getDataSource();
$subQuery = $db->buildStatement(
array(
'fields' => array('MAX(id)'),
'table' => $db->fullTableName($this->AccountRequest),
'alias' => 'MaxRecord',
'limit' => null,
'offset' => null,
'order' => null,
'group' => array("user_id")
),
$this->AccountRequest
);
$searching_parameters = array(
#"AccountRequest.id IN " => "(SELECT MAX( id ) FROM `account_requests` GROUP BY user_id)"
"AccountRequest.id IN " => "(".$subQuery.")"
);
$this->Paginator->settings = array(
#'fields' => array('AccountRequest.*'),
'conditions' => $searching_parameters,
'limit' => $limit,
'page' => $page_number,
#'group' => array("AccountRequest.user_id"),
'order' => array(
'AccountRequest.id' => 'DESC'
)
);
$data = $this->Paginator->paginate('AccountRequest');
This structure is producing a query is:
SELECT
`AccountRequest`.`id`,
`AccountRequest`.`user_id`,
`AccountRequest`.`email`,
`AccountRequest`.`emailchange`,
`AccountRequest`.`email_previously_changed`,
`AccountRequest`.`first_name`,
`AccountRequest`.`first_namechange`,
`AccountRequest`.`f_name_previously_changed`,
`AccountRequest`.`last_name`,
`AccountRequest`.`last_namechange`,
`AccountRequest`.`l_name_previously_changed`,
`AccountRequest`.`reason`,
`AccountRequest`.`status`,
`AccountRequest`.`created`,
`AccountRequest`.`modified`
FROM
`syonserv_meetauto`.`account_requests` AS `AccountRequest`
WHERE
`AccountRequest`.`id` IN '(SELECT MAX(id) FROM `syonserv_meetauto`.`account_requests` AS `MaxRecord` WHERE 1 = 1 GROUP BY user_id)'
ORDER BY
`AccountRequest`.`id` DESC
LIMIT 25
In the subquery, its add an extra single quote so it's producing an error.
So, How can I remove these single quotes from this subquery?
Thanks
What are you trying to achieve with the sub query?
The MAX(id) just means it will pull the id with the largest value AKA the most recent insert. The sub query is completely redundant when you can just ORDER BY id DESC.
using MAX() will return only one record, if this is what you want to achieve you can replicate by adding LIMIT 1
If the sub query is just an example and is meant to be from another table I would just run the query that gets the most recent id before running the main query. Getting the last inserted id in a separate query is very quick and I cant see much of a performance loss. I think it will result in cleaner code that`s easier to follow to.
edit 1: From the comments it sounds like all your trying to get is a particular users latest account_requests.
You dont need the sub query at all. My query below will get the most recent account record for the user id you choose.
$this->Paginator->settings = array(
'fields' => array('AccountRequest.*'),
'conditions' => array(
'AccountRequest.user_id' => $userID // you need to set the $userID
)
'page' => $page_number,
'order' => array(
'AccountRequest.id DESC' //shows most recent first
),
'limit' => 1 // set however many you want the maximum to be
);
The other thing you cold be meaning is to get multiple entries from multiple users and display them in order of user first and then the order of recent to old for that user. MYSQL lets you order by more than one field, in that case try:
$this->Paginator->settings = array(
'conditions' => array(
'AccountRequest.user_id' => $userID // you need to set the $userID
)
'page' => $page_number,
'order' => array(
'AccountRequest.user_id', //order by the users first
'AccountRequest.id DESC' //then order there requests by recent to old
)
);
If the example data you have added into the question is irrelevant and you are only concerned about how to do nested subqueries it has already been answered here
CakePHP nesting two select queries
However I still think based on the data in the question you can avoid using a nested query.

how to sort a table by default descending order cakephp [duplicate]

This question already exists:
sort a data table header only in that page cakephp
Closed 7 years ago.
I would like to know how to sort a table header only in that page without sorting the whole table.is this possible in cakephp? please show me some sample code. my view is
<?php
echo $url = $this->Paginator->sort('ID', 'id',array('direction' => 'desc'));
$arrow = getArrow($url);
?>
This is my Controller:
$this->paginate = Set::merge($this->paginate, array('OrderFinalized' => array(
'limit'=>4,
'conditions' => $condition_ary,
'joins' => array(
array(
'table' => 'order_entry_headers',
'alias' => 'OrderEntryHeaders2',
'type' => 'inner',
'foreignKey' => false,
'conditions' => array('OrderEntryHeaders2.id = OrderFinalized.order_entry_headers_id'),
'order' => array(
'OrderEntryHeaders2.id'=> 'desc'
)
),
this is the query:
$result = $this->OrderEntryHeader->query("SELECT (value+1) as val FROM order_entries_seq ORDER BY OrderEntryHeader.id desc ");
When I sort the first page desending order I get the last results from the database table.i want to sort only the results from that page.it should not change while navigation.
ex- id name (page 1) ASC
1 A
2 B
3 C
4 D
DESC id name
4 D
3 C
2 B
1 A
What you want is to retrieve data from a database and then use the sorting. The easiest way is by using JavaScript.
You need front-end / client-side table sorter like
http://tablesorter.com/docs/#Demo
is it still possible to do with sort function?
It is possible in CakePHP, make array sort in afterFind method

Sort table header in descending order page wise without sorting whole database table [duplicate]

This question already exists:
sort a data table header only in that page cakephp
Closed 7 years ago.
I would like to know how to sort a table header only in that page without sorting the whole table.is this possible in cakephp? please show me some sample code. my view is
<?php
echo $url = $this->Paginator->sort('ID', 'id',array('direction' => 'desc'));
$arrow = getArrow($url);
?>
This is my Controller:
$this->paginate = Set::merge($this->paginate, array('OrderFinalized' => array(
'limit'=>4,
'conditions' => $condition_ary,
'joins' => array(
array(
'table' => 'order_entry_headers',
'alias' => 'OrderEntryHeaders2',
'type' => 'inner',
'foreignKey' => false,
'conditions' => array('OrderEntryHeaders2.id = OrderFinalized.order_entry_headers_id'),
'order' => array(
'OrderEntryHeaders2.id'=> 'desc'
)
),
this is the query:
$result = $this->OrderEntryHeader->query("SELECT (value+1) as val FROM order_entries_seq ORDER BY OrderEntryHeader.id desc ");
When I sort the first page desending order I get the last results from the database table.i want to sort only the results from that page.it should not change while navigation.
ex- id name (page 1) ASC
1 A
2 B
3 C
4 D
DESC id name
4 D
3 C
2 B
1 A
What you want is to retrieve data from a database and then use the sorting. The easiest way is by using JavaScript.
You need front-end / client-side table sorter like
http://tablesorter.com/docs/#Demo
is it still possible to do with sort function?
It is possible in CakePHP, make array sort in afterFind method

CakePHP order not working

Hi i am using CakePHP version - 2.5.5.
I have a table name chat_ategory_mages I want to get Average number of Frequency Order by Descending. Know about the Frequency please check - How to get Average hits between current date to posted date in MySQL?
chat_ategory_mages
id chat_category_id hits created
------------------------------------------------
1 5 10 2014-11-07 11:07:57
2 5 8 2014-11-10 05:10:20
3 5 70 2014-10-04 08:04:22
Code
$order=array('Frequency' => 'DESC');
$fields=array(
'ChatCategoryImage.id',
'ChatCategoryImage.chat_category_id',
'ChatCategoryImage.created',
'ChatCategoryImage.hits',
'hits/(DATEDIFF(NOW(),created)) AS Frequency',
);
QUERY-1
$rndQry=$this->ChatCategoryImage->find('all',array('conditions'=>array('ChatCategoryImage.chat_category_id'=>$cetegory_id), 'fields'=>$fields, 'order'=>$order, 'limit'=>10));
pr($rndQry); //WORKING FINE
QUERY-2
//THIS IS NOT WORKING
$this->Paginator->settings = array(
'conditions'=>array('ChatCategoryImage.chat_category_id'=>$cetegory_id),
'fields'=>$fields,
'limit' => 10,
'order' => $order,
);
$getCategoryImages = $this->Paginator->paginate('ChatCategoryImage');
pr($getCategoryImages); //NOT WORKING
Above table if i write simple cakephp query the order is working fine but when i am using cakephp pagination it is not working. If i am using $order=array('hits' => 'DESC'); this its woring perfect. Showing result 70,10,8 consistently but when i am adding Frequency it the result not coming the descending order.
Mysql Query
QUERY-1 :
SELECT ChatCategoryImage.id, ChatCategoryImage.chat_category_id, ChatCategoryImage.hits, ChatCategoryImage.created, hits/(DATEDIFF(NOW(),created)) AS Frequency, FROM myshowcam.chat_category_images AS ChatCategoryImage WHERE ChatCategoryImage.chat_category_id = 5 ORDER BY Frequency DESC LIMIT 10
QUERY-2 :
SELECT ChatCategoryImage.id, ChatCategoryImage.chat_category_id, ChatCategoryImage.hits, ChatCategoryImage.created, hits/(DATEDIFF(NOW(),created)) AS Frequency, FROM myshowcam.chat_category_images AS ChatCategoryImage WHERE ChatCategoryImage.chat_category_id = 5 LIMIT 10
What is the problem and why its not coming ORDER BY Frequency in the second query?
Thanks
chinu
You can use virtualFields
$this->ChatCategoryImage->virtualFields = array('Frequency' => 'hits/(DATEDIFF(NOW(),created))');
changing the way of order
$order = array('Frequency' => 'desc');
This happened to me to. You have to add to the paginate function the third parameter $whitelist. For example.
$this->Paginator->settings = array(
'conditions'=>array('ChatCategoryImage.chat_category_id'=>$cetegory_id),
'fields'=>$fields,
'limit' => 10,
'order' => $order,
);
$scope = array();
$whitelist = array('ChatCategoryImage.id', ...); //The fields you want to allow ordering.
$getCategoryImages = $this->Paginator->paginate('ChatCategoryImage', $scope, $whitelist);
pr($getCategoryImages);
I do not know why this is happening. I tried to see the code inside the paginate function but i could not figure it out.
Your code was lil wrong
$this->paginate = array(
'conditions' => array('ChatCategoryImage.chat_category_id'=>$cetegory_id),
'limit' => 10, 'order' => 'Frequency' => 'DESC');
$getAllCourses = $this->paginate('ChatCategoryImage');

cant order by pending status

I want to get the results of all the rows with a pending status and after that display the rest that dont have pending . I cant get the syntax right to order the data this way . I want all the pending value rows and then all the other non-pending rows.
$this->Paginator->settings = array(
// 'conditions' => array('request_status' => 'pending') ,
'order' => array('request_status' => 'pending','request_date'=> 'desc'),
'limit' => 5 );
'request_status' => 'pending' should be either 'request_status' => 'asc' or 'request_status' => 'desc' depending on preference. It doesn't belong in the order conditions as you have specified as its part of a WHERE clause and not an ORDER BY
EDIT:
IF its a standard display that you're looking to render, then use the model rather than pagination settings. I had difficulty with them before. So in the model you would define an order variable
public $order = array("request_status" => "ASC");
or
public $order = array("request_status" => "DESC");
In the controller for a view, it would be a case of calling the standard
$this->set('mydata' , $this->Paginator->paginate);
You can sort on multiple columns, and you can sort different columns in different directions. For example, to sort by type of request_date in descending order, then by request_status within request_type in descending order ('youngest' request_date first), use the following query:
mysql> SELECT * FROM pet
-> ORDER BY request_status, request_date DESC;
CakePHP:
'order' => array('request_status, request_date DESC');
The DESC keyword applies only to the column name immediately preceding it (request_date); it does not affect the request_status column sort order yet will group them. In other words, above sql query will group request_status fields ordered by their request_date fields.
Another useful link for paginator sorting it's this one.

Categories