Cakephp How to use SQL month function in cakephp find method - cakephp

I have a query like
SELECT count(id),DATE_FORMAT(created,'%M') from searches group by month(created)
The output that I got like
count(id) DATE_FORMAT(created,'%M')
16 August
2 September
I applied this query in cakephp find method like below
$total = $this->Searches->find('count',[
'fields'=>['Searches.id',DATE_FORMAT('created','%M')],
'group' =>[month('Searches.created')]
]);
1st I am getting error date_format() expects parameter 1. How can I apply my top sql query in cakephp find method ?
I am using cakephp 3 version.

The query builder has a func() method that allows you to use SQL functions.
http://book.cakephp.org/3.0/en/orm/query-builder.html#using-sql-functions
$time = $query->func()->date_format([
'created' => 'identifier',
"'%M'" => 'literal'
]);
You can then use that $time variable in your query.

Related

CakePHP query: where condition with calculated fields

I have the followwing problem with creating a query in CakePHP 3:
For the Entity Recordings I want to calculate the age as the difference between the year of the two dates "collection date" and "birthdate"
$query = $this->Recordings->find()
->select(['age' => 'Year(Recordings.collection_date) - Year(Athletes.birthdate)'])
->select($this->Recordings)
->select($this->Recordings->Athletes);
When I try to filter with the following where clause
$query = $query->where(['Year(Recordings.collection_date) - Year(Athletes.birthdate) =' => $age]);
The SQL Code which is created has the Athletes beeing modified to lowercase.
WHERE
( Year(Recordings.collection_date) - year(athletes.birthdate) = '17' )
How do I have to write the where clause correctly? I havent found a way to use Identifiers or query functions like
$year = $q->func()->year(['Athletes.birthdate' => 'identifier']);
to bild the conditions.
Any hints are welcome.

Filter on date from datetime in query builder (CakePHP 3)

I have a datetime field in my model. In a query I want to select all rows created on a specific day/date (the time doesn't matter). What is the simplest way of doing that in CakePHP 3.8 ?
Per other answers, use of a custom function to cast the column with MySQL DATE() may slow your query down at scale. Besides, there's probably nothing simpler than plain arrays to build conditions:
$query = $this->YourTable->find()
->where([
'date_field >=' => '2020-01-01 00:00:0', // Or pass a Time() object..
'date_field <' => '2020-01-02 00:00:00',
]);
This kind of stuff is covered in the Query Builder docs.

Pagination of query ignoring the LIMIT clause in CakePHP 3.x

I am trying to create a query that would only return 2 results, and by following the documentation I get the query to run, however the limit is still set to 20 by default.
Here is how the query is built:
$upcomingMeetings = $this->Meetings->find('all')
->where(['Meetings.user_id' => $this->Auth->User('user_id')])
->andWhere(["Meetings.date >= " => date('Y-m-d') ])
->order(['Meetings.date' => 'ASC'])
->limit(2);
The result is being passed to the view like following:
$this->set('upcomingMeetings', $this->paginate($upcomingMeetings));
Here is the query that is being run on the database:
SELECT
Meetings.id AS `Meetings__id`,
Meetings.date AS `Meetings__date`,
Meetings.user_id AS `Meetings__user_id`,
FROM
meetings Meetings
WHERE
(
Meetings.group_id = 7
AND Meetings.date >= '2016-01-14'
)
ORDER BY
Meetings.date ASC
LIMIT
20 OFFSET 0
Any help or guidance is much appreciated.
When paginating a Query object, CakePHP will ignore the limit() clause and use the value defined in the $paginate configuration array instead.
This is what can be concluded after inspecting the source code.
Try adding the following to your controller:
public $paginate = [
'limit' => 2,
];

CakePHP 3 format date in select query

I am using CakePHP 3 in my project and I came across of a need to format date for date_joined and date_inactivefield in my report. I can use native select query with date function to format date for the field, but in CakePHP, I am not sure how can I integrate date format in select query.
$query = $this->CustomersView->find();
$query->select(['id','contact_person',''date_joined',
'date_inactive','comments','status']);
$query->toArray();
UPDATE
I also tried one of the example from CakePHP online resource
$date = $query->func()->date_format([
'date_joined' => 'literal',
'%m-%d-%y' => 'literal'
]);
$query->select(['id','contact_person',''date_joined',
'date_inactive','comments','status']);
$query->toArray();
But it throws me error below:
'Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%m-%d-%y)) AS `datejoined`, CustomersView.date_inactive AS `CustomersView__date_' at line 1'
SQL query generated by CakePHP:
SELECT CustomersView.id AS `CustomersView__id`,
CustomersView.contact_person AS `CustomersView__contact_person`,
(date_format(date_joined, %m-%d-%y)) AS `datejoined`,
CustomersView.date_inactive AS `CustomersView__date_inactive`,
CustomersView.comments AS `CustomersView__comments`,
CustomersView.status AS `CustomersView__status`
FROM customers_view CustomersView
Any help is really appreciated. :)
Thanks,
Ray
If the date fields are of an appropriate type in your schema (e.g. DATETIME), Cake will return DateTime objects that can be formatted using plain PHP - you don't need to do it in the select.
Example:
$query = $this->CustomersView->find();
$query->select(['id','contact_person','date_joined',
'date_inactive','comments','status']);
$array = $query->toArray();
foreach ($array as $row) {
echo $row["date_joined"]->format("dMY");
}
Let's say for example that your query only returned one row, and the date_joined field here was set to 2015-12-21 23:55:00. The above code would simply print out 21Dec2015.
You can use the DATE_FORMAT($field, %d-%m-%Y) from MySQL.
Here it is an example:
$query = $this->CustomersView->find();
$query->select(['id','contact_person',''DATE_FORMAT(date_joined, "%d-%m-%Y")',
'date_inactive','comments','status']);
Fixed the problem with below code:
$query = $this->CustomersView->find();
$date = $query->func()->date_format([
'date_joined' => 'literal',
"'%m-%d-%y'" => 'literal'
]);
$query->select(['id', 'contact_person', 'date_joined' => $date,
'date_inactive', 'comments', 'status']);
$query->toArray();

how using SQL IN operator in find method of cakephp ORM

i am beginner in cakephp , and i want use SQL IN operator in find method , i have words table.
my code is :
$this->Word->find('Word.wordid in (83,82)');
, and this code create this query :
SELECT `Userword`.`userwordid`, `Userword`.`userid`, `Userword`.`wordid`,
`Userword`.`date`, `Userword`.`levelid` FROM `userwords` AS `Userword` WHERE
`Userword`.`wordid` = (82)
but i need this query
SELECT `Userword`.`userwordid`, `Userword`.`userid`, `Userword`.`wordid`,
Userword`.`date`, `Userword`.`levelid` FROM `userwords` AS `Userword` WHERE
`Userword`.`wordid` IN (83,82)
how can getting like this query (using IN operator )
thanks.
you need to let cake take care of that - simply use it as it was a string (but make sure it is an array):
$arrayOfIds = [1, 5, ...];
$this->Word->find('all', array(
'conditions' => array('Word.wordid' => $arrayOfIds)
));

Resources