How to do a timediff or datediff query in CakePHP - php

I want to run this query:
SELECT * FROM `foobar`
where
TIMESTAMPDIFF(MINUTE,request_time,NOW()) < 15
I have tried:
$this->find('first',
array('conditions' =>
array('username' => $v['User']['username']),
'TIMESTAMPDIFF(MINUTE,request_time,NOW()) < ' => 15));

You have to place the SQL fragment inside of the conditions array, currently it's placed outside and thus it's being ignored.
$this->find('first', array
(
'conditions' => array
(
'username' => $v['User']['username'],
// this is where it needs to go
'TIMESTAMPDIFF(MINUTE, request_time, NOW()) < ' => 15
)
// this is where it was before
));
That will result in a query similar to this:
SELECT
`Model`.`username`, ...
FROM
`db`.`model` AS `Model`
WHERE
`username` = 'whatever'
AND
TIMESTAMPDIFF(MINUTE, request_time, NOW()) < 15
LIMIT 1
By default CakePHP will include all fields in the SELECT statement.
Obviously if you want the query to use only the TIMESTAMPDIFF condition as in your example, then you have to drop 'username' => $v['User']['username'].

Related

Group SQL query results by year

I'm new in SQL and I need to group the results of a query by year.
In other words, I have this table structure:
id | title | date
My current query SELECT * FROM table
My current result:
array =>
0 =>
array =>
...
'date' => string '2018-03-09'
1 =>
array =>
...
'date' => string '2018-03-15'
2 =>
array =>
...
'date' => string '2017-03-15'
And I need something like that:
array =>
0 =>
array =>
...
'date' => string '2018-03-09'
array =>
...
'date' => string '2018-03-15'
1 =>
array =>
...
'date' => string '2017-03-15'
Thanks in advance for help :)
[EDIT]
I finally found a way to do what I wanted:
$result = $sql->query("SELECT * FROM abstract ORDER BY date DESC");
$array = [];
forEach($result as $res) {
$year = strtok($res['date'], '-');
if (!isset($array[$year]))
$array[$year][0] = $res;
else
array_push($array[$year], $res);
}
return $array;
If you want group data by year.
Select id,title,date,DATE_FORMAT(date, '%Y') YEAR_GRP from table group by YEAR_GRP
This is something you'll want to do in your query, as MySQL can do it much more efficiently, than PHP.
The way to do it is to add a GROUP BY clause to your query, which will batch rows in your resultset into a single row, based on a grouping value, which in your case will be YEAR(date), as you're looking to group items by the year component in each line's date.
Because you're still looking to have all the results returned, merely grouped by each distinct grouping value, you'll need to use an Aggregate Function to combine all the matching lines into an array of values. Luckily MySQL has a function called json_objectagg which does exactly what you need.
So you'll end up with a query that looks something like:
SELECT year(`date`) AS `year`, json_objectagg(id, `date`, title) AS `line`
FROM abstract
GROUP BY `year`
Instead of json_objectagg, alternatives are e.g. json_arrayagg
SELECT year(`date`) AS `year`, json_arrayagg(id, `date`, title) AS `line`
...or group_concat
SELECT year(`date`) AS `year`, group_concat(id, `date`, title) AS `line`
...depending on what kind of output you require.

How to convert a mysql query in CakePHP pagination condition

I have below MySQL query.
I just want to convert a MySQL query in CakePHP pagination condition. So that i can get result.
MySql Query:
SELECT *, 3963 * acos(cos(radians(90-lat ))*cos(radians(90-'".$result['lat']."'))".
"+sin(radians(90-lat ))* sin(radians(90-'".$result['lat']."'))".
"*cos(radians(lng- '".$result['lng']."'))) AS distance FROM member"." HAVING (distance < 5) ORDER BY distance ASC
i am using this PHP Code
$condition = array('Member.is_deleted !=' => 1, 'Member.status !=' => 0, 'OR' => array());
$this->paginate = array(
'conditions' => $condition,
'fields' => array()
);

mysql "between date" query works in phpmyadmin but returns nothing with PDO

When i try to run this with php/pdo the result is empty, but when i replace the variables and echo the query and copy paste to phpmyadmin it works as it should.
I guess that it have something to do with the BETWEEN part in the query, it works if I remove it.
php code:
$sql = 'SELECT * from `activity`
WHERE `activity`.`employee_id` = :id
AND `activity_endtime` BETWEEN :start
AND :end
ORDER BY :order LIMIT 0 ,:limit';
$date_end = date('Y-m-d',time());
$date_start = date('Y-m-01',strtotime($date_end));
$values = array(
':id' => $_SESSION['user_id'],
':start' => '"'.$date_start.'"',
':end' => '"'.$date_end.'"',
':order' => 'activity_id',
':limit' => '10');
$q->execute($values);
while($r = $q->fetch(PDO::FETCH_ASSOC)){
//does not get here after adding the between part
}
The query that i get from replacing the parameters and echoing:
SELECT * from `activity`
WHERE `activity`.`employee_id` = 7
AND `activity_endtime` BETWEEN "2014-08-01"
AND "2014-08-18"
ORDER BY activity_id LIMIT 0 ,10
Don't wrap the values with quotes.
Change
':start' => '"'.$date_start.'"',
':end' => '"'.$date_end.'"',
to
':start' => $date_start,
':end' => $date_end,
and let me know if it worked for you.

CakePHP SQL Operation using 'OR'

I am using CakePHP find to retrieve the data. I need to use OR between conditions so i used following query as stated in CakePHP documentation. This works perfectly other times but the problem arises when the field name is same in OR array, Group.arrival_date in this case.
$this->Group->find('all',
array('conditions' => array(
'OR' => array(
'Group.arrival_date' => 'DATE_ADD(CURDATE(), INTERVAL 30 DAY)',
'Group.arrival_date' => 'DATE_ADD(CURDATE(), INTERVAL 7 DAY)'
)
)
));
The SQL it generate is
SELECT `Group`.`id`, `Group`.`rr_no`, `Group`.`package_id`, `Group`.`user_id`,
`Group`.`group_name`, `Group`.`pax`, `Group`.`agent_id`, `Group`.`staff_id`,
`Group`.`arrival_date`, `Group`.`departure_date`, `Group`.`status`, `Group`.`slug`,
`Group`.`book_flight`, `Group`.`allocated_tents`, `Group`.`alert`, `Group`.`alert_seen`
FROM `groups` AS `Group` WHERE `Group`.`arrival_date` = 'DATE_ADD(CURDATE(), INTERVAL 7 DAY)'
It takes the second condition only. For different field name like:
$this->Group->find('all',
array('conditions' => array(
'OR' => array(
'Group.slug' => 'slug1',
'Group.group_name' => 'group1'
)
)
));
The generated SQL is
SELECT `Group`.`id`, `Group`.`rr_no`, `Group`.`package_id`, `Group`.`user_id`,
`Group`.`group_name`, `Group`.`pax`, `Group`.`agent_id`, `Group`.`staff_id`,
`Group`.`arrival_date`, `Group`.`departure_date`, `Group`.`status`, `Group`.`slug`,
`Group`.`book_flight`, `Group`.`allocated_tents`, `Group`.`alert`, `Group`.`alert_seen`
FROM `groups` AS `Group` WHERE ((`Group`.`slug` = 'slug1') OR (`Group`.`group_name` = 'group1'))
Which is as expected. What am i missing in the first find i used? How can i get the above query work? Any help would be greatly appreciated. I am using CakePHP 2.0.
Try:
$this->Group->find('all',
array('conditions' => array(
'OR' => array(
array('Group.arrival_date' => 'DATE_ADD(CURDATE(), INTERVAL 30 DAY)'),
array('Group.arrival_date' => 'DATE_ADD(CURDATE(), INTERVAL 7 DAY)')
)
)
));
Or you could use IN:
$this->Group->find('all',
array('conditions' => array(
'Group.arrival_date' => array('DATE_ADD(CURDATE(), INTERVAL 30 DAY)', 'DATE_ADD(CURDATE(), INTERVAL 7 DAY)')
)
);
For same field, simply put all values you need for OR in an array.
$this->Group->find('all',
array('conditions' => array(
'Group.arrival_date' =>
array('DATE_ADD(CURDATE(), INTERVAL 30 DAY)', 'DATE_ADD(CURDATE(), INTERVAL 7 DAY)' )
)
));

how to use LIKE with conditions in sqlite or mysql with lithium recordset

so I can look for concrete values by doing
$recordset= Model::find('all', array(
'conditions' => array(
'condition' => $somevalue
)
))
however, what do I do if I want to match on a partial value?
right now, I've resorted to writing the query myself, a la:
$abc = Connections::get('default')->
read('SELECT * FROM myTable WHERE condition LIKE "%partial string%"');
Here's how I do an SQL 'like' search:
$user = User::find('all', array(
'conditions' => array(
'first_name' => array('like' => '%yeun%'))
)
);
'like' being the keyword, there.
That would generate a query like:
SELECT * FROM `users` AS `Users` WHERE (`first_name` like '%yeun%');
Hope that helps.

Categories