How to convert a mysql query in CakePHP pagination condition - php

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()
);

Related

CakePHP 3.6: Count distinct records from table

I am trying to achieve a distinct count on a table with a where condition.
This is what I have tried:
$customerServiceTypes = TableRegistry::get('CustomerServiceTypes');
$customers_count = $customerServiceTypes->find('all', array(
'fields' => 'DISTINCT CustomerServiceType.customer_id',
'conditions' => array("CustomerServiceTypes.service_type_id" => $id)))->count();
But its not working. I get 25 as result but it should be 2. Distinct is not working.
$customerServiceTypes = TableRegistry::get('CustomerServiceTypes');
$customers_count = $customerServiceTypes->find()
->select(['customer_id'])
->distinct()
->where(['service_type_id =' => $id])->count();

How to use where and group by conditions with cakephp2?

I'm new to cakephp2 and I wanted to ask you a little favor.I'm currently learning cakephp2 but I'm having some hard time trying to understand how to use where and groupby clause in cakephp2.
I am tring to convert this sql query below to cakphp2 but how will I do it using find() ?
select params,count(params) from pv_logs
where dt = '2014/9/25' and is_crawler = 0
group by params order by count(params) desc limit 100 ;
This is how I did it in cakephp2 format but do you see something wrong with this ?
$pvcount = $this->PvLog->find('all', array(
'fields' => array('dt','params','count(params)'),
'conditions'=>array('PvLog.dt'=>'2014/9/25','PvLog.is_crawler'=>0),
'group'=>array('PvLog.params'),
'order'=>array('PvLog.count(params)'),
'limit' => 100,
));
Try Below
$this->PvLog->virtualFields['params_count']='count(params)';
$pvcount = $this->PvLog->find('all', array(
'fields' => array('dt','params','params_count'),
'conditions'=>array('PvLog.dt'=>'2014-09-25','PvLog.is_crawler'=>0),
'group'=>array('PvLog.params'),
'order'=>array('params_count'=>'asc'),
'limit' => 100,
));

cakephp complex queries

How can I transform the SQL statement into the CakePHP Code? I am able to get the group by result. But how can I add the inner Select Count(*) statement?
I've updated the code under "Revised" However, I am getting this error. Parse error: syntax error, unexpected 'INCOMPLETE' (T_STRING), expecting ')'. I am sure I check my open and close brackets.
SQL Statement below
SELECT
`id` ,
`mtpToken` ,
`mtpCreator_id` ,
`school_id` ,
`user_id` ,
`mtpStatus` ,
`created` ,
`modified` ,
(
(SELECT COUNT( * ) FROM mtpScreenings
WHERE (mtpStatus = 'INCOMPLETE' OR mtpStatus = 'HALFWAY') AND mtpToken = `mtpToken` )
) AS `mainStatus`
FROM `mtpScreenings` WHERE `mtpScreenings`.`school_id` = 15 GROUP BY `mtpToken`
CakePHP Code below
$setting = $this->paginate = array(
conditions' => array('MtpScreening.school_id' => 15),
'recursive' => -1,
'fields' => array('MtpScreening.field1'),
'group' => array('MtpScreening.mtpToken'),
'limit' => 1000
);
Revised
$setting = $this->paginate = array(
conditions' => array('MtpScreening.school_id' => 15),
'recursive' => -1,
'fields' => array('SELECT COUNT(*) FROM mtpScreenings
WHERE (mtpStatus = "INCOMPLETE" OR mtpStatus = "HALFWAY") AND mtpToken = `mtpToken`
) AS mainStatus'),
'group' => array('MtpScreening.mtpToken'),
'limit' => 1000
);
Virtual Field
Code example of virtual field:
public $virtualFields = array(
'count' => "SELECT COUNT( * ) FROM MtpScreening
WHERE (MtpScreening.mtpStatus = 'INCOMPLETE' OR MtpScreening.mtpStatus = 'HALFWAY') AND MtpScreening.mtpToken = 'mtpToken'"
);
This code will produce virtual field:
$this->find('all', array(
'fields'=>array(
'MtpScreening.id',
'MtpScreening.mtpToken',
'MtpScreening.mtpCreator_id',
'MtpScreening.school_id',
'MtpScreening.count'/*virtual field*/
)
)
);
Pagination and virtual fields
Since virtual fields behave much like regular fields when doing
find’s, Controller::paginate() will be
able to sort by virtual fields too.

How to do a timediff or datediff query in CakePHP

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'].

Cakephp joining tables via find option not working

I'm trying to join a Users table to my curent hasMany Through table which has Interest and User model id's.
Below is the find query with options:
$params = array(
'fields' => array('*', 'COUNT(DISTINCT(InterestsUser.interest_id)) as interest_count'),
'limit' => 15,
'recursive' => -1,
'offset' => $offset,
'conditions' => array('InterestsUser.interest_id' => $conditions),
'group' => array('InterestsUser.user_id'),
'order' => array('interest_count DESC', 'InterestsUser.user_id ASC', 'InterestsUser.interest_id ASC'),
'joins' => array(
array('table' => 'users',
'alias' => 'User',
'type' => 'LEFT',
'conditions' => array(
'User.id' => 'InterestsUser.user_id',
)
)
)
);
$results = $this->InterestsUser->find('all', $params);
This returns InterestsUser table fine but does not return any values for Users table. It only returns field names.
What could be wrong?
UPDATE:
OK, above is generating below SQL which I got from Cake's datasources sql log:
SELECT *, COUNT(DISTINCT(InterestsUser.interest_id)) as interest_count
FROM `interests_users` AS `InterestsUser`
LEFT JOIN users AS `User` ON (`User`.`id` = 'InterestsUser.user_id')
WHERE `InterestsUser`.`interest_id` IN (3, 2, 1)
GROUP BY `InterestsUser`.`user_id`
ORDER BY `interest_count` DESC, `InterestsUser`.`user_id` ASC, `InterestsUser`.`interest_id` ASC
LIMIT 15
Why is users table values returning NULL only for all fields?
UPDATE:
OK I tried below but this is working fine...What am I missing here!!??
SELECT * , COUNT( DISTINCT (
interests_users.interest_id
) ) AS interest_count
FROM interests_users
LEFT JOIN users ON ( users.id = interests_users.user_id )
WHERE interests_users.interest_id
IN ( 1, 2, 3 )
GROUP BY interests_users.user_id
ORDER BY interest_count DESC
LIMIT 15
The array syntax for join conditions should be like the following
array('User.id = InterestsUser.user_id')
as opposed to array('User.id' => 'InterestsUser.user_id'). For more, see http://book.cakephp.org/view/1047/Joining-tables.

Categories