CakePHP: Select DISTINCT in ContainableBehaviour - cakephp

I am trying to select only distinct related model entries but it seems it doesn't work.
I have this:
$active_questions = $this->Question->find('all', array('conditions' => array('test_id' => $active_tests), 'fields' => array('answer_style_id'), 'contain' => array(
'Answer' => array(
'fields' => array('capital_category_id'),
'CapitalCategory' => array(
'fields' => array('id', 'DISTINCT capital_id', 'DISTINCT category_id', 'delete_flag'),
'Capital' => array(
'fields' => array('id', 'delete_flag')
),
'Category' => array(
'fields' => array('id', 'delete_flag')
)
)
)
)));
But Cake seems to automatically add the associated model key, even id I specified it with a DISTINCT keyword:
Query: SELECT `CapitalCategory`.`id`, DISTINCT `CapitalCategory`.`capital_id`, DISTINCT `CapitalCategory`.`category_id`, `CapitalCategory`.`delete_flag`, `CapitalCategory`.`capital_id`, `CapitalCategory`.`category_id` FROM `capital_categories` AS `CapitalCategory` WHERE `CapitalCategory`.`id` = 217
How do I filter out only DISTINCT capitals or categories? For the current example, Cake returns 20 categories with the same id. I want only one to be returned.
Thank you.

Off the top of my head, the following may work using the 'group' option
$active_questions = $this->Question->find(
'all',
array(
'conditions' => array('Question.test_id' => $active_tests),
'fields' => array('answer_style_id'),
'contain' => array(
'Answer' => array(
'fields' => array('capital_category_id'),
'CapitalCategory' => array(
'fields' => array('id', 'capital_id', 'category_id', 'delete_flag'),
'group' => array('capital_id', 'category_id'),
'Capital' => array(
'fields' => array('id', 'delete_flag')
),
'Category' => array(
'fields' => array('id', 'delete_flag')
)
)
)
)
)
);

Why don't you put 'group' just below 'fields' and not inside 'contain', also you may have to remove 'fields' altogether.

Related

Join and Count Tables in cakePHP

thanks to the help i have gotten on Stackoverflow while learning php i am able to Join tables and use Count.
I am unable to do both in one query.
I am wanting to count records in a joined table.
This is what i have tryed and i seem to get errors:
$options = array(
'fields' => array(
'toutcome.AffCommission',
),
'joins' => array(
array(
'conditions' => array(
'tapplicant.AppID = toutcome.AppID',
),
'table' => 'toutcome',
'alias' => 'Toutcome',
'type' => 'join',
),
),
'limit' => 'Toutcome',
'offset' => 'Toutcome',
'contain' => array(
'Toutcome',
),
);
$data = $this->Tapplicant->find('count', $options);
$this->set('count', $data );
Try this
$options = array(
'fields' => array(
'toutcome.AffCommission',
),
'joins' => array(
array(
'conditions' => array(
'tapplicant.AppID = toutcome.AppID',
),
'table' => 'toutcome',
'alias' => 'Toutcome',
'type' => 'join',
),
),
'limit' => n, // its should be integer
'offset' => n, // its should be integer
'contain' => array(
'Toutcome',
),
);

CakePHP join only the latest entry

I have 2 tables :
ORDERS
------
id
type
LOGS
----
id
order_id
time
I want to query with cakephp so I have :
array(
'Order' => array(
'id' => '38',
'type' => 'online',
),
'Log' => array(
'time' => '2014-09-24 21:17:14'
)
)
The problem is that I want only the last order, not all orders with all logs.
I did something like this :
$ordersList = $this->Order->find('all', array(
'fields' => array(
'Order.*',
'Log.time'
),
'joins' => array(
array(
'table' => 'logs',
'alias' => 'Log',
'type' => 'right',
'conditions' => array(
'Log.order_id = Order.id'
),
)
),
);
To have only the last one, you can order the result by log.time and then take only the first record (with the param 'first' or just by fetching the first record of the recordset).
For example :
$order = $this->Order->find('first', array(
'order' => array('Log.time' => 'desc')
));
in your case :
$ordersList = $this->Order->find('first', array(
'fields' => array(
'Order.*',
'Log.time'
),
'joins' => array(
array(
'table' => 'logs',
'alias' => 'Log',
'type' => 'right',
'conditions' => array(
'Log.order_id = Order.id'
),
'order' => array('Log.time' => 'desc')
)
),
);
As information, if you want to have a simple method to join the models, take a look at the containable behavior. With this behavior, the link are setted in the model then you only have to declare which associated model you want to retrieve with your current model.
=> http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html

cakephp paginate with associated model

User has many User_Questionaries. I want paginate users that have particular questionnaire. I used following pagination for it.
$paginate = array(
'conditions' => array(
'User.role' => IWOA,
'UserQuestionary.questionary_id' => $id
),
'recursive' => 1,
'limit' => 10,
'order' => array(
'name' => 'asc'
),
'contain' => array('UserQuestionary')
);
But it is not create join query. It is showing Unknown column UserQuestionary.questionary_id' in 'where clause'
What is the issue? How can i do it?
Finally I used join query for do this.
$paginate = array(
'conditions' => array(
'Iwoa.role' => IWOA,
),
'joins' => array(
array(
'alias' => 'UserQuestionary',
'table' => 'user_questionaries',
'type' => 'LEFT',
'conditions' => 'UserQuestionary.user_id = Iwoa.id AND UserQuestionary.questionary_id = ' . $id
)
),
'limit' => 10,
'order' => array(
'name' => 'asc'
),
);

CakePHP 2.1 Custom Pagination

I am using cakephp 2.1 and defined 3 tables as follows.
`industries(id, name);`
`movies(id, name, industry_id),`
`trailers(id, name, movie_id);`
I want to paginate the trailers for particular industry. So the code I have written is below:
$this->paginate = array(
'Industry' => array(
'contain' => array(
'Movie' => array(
'order' => 'Movie.release DESC',
'Trailer' => array(
'conditions' => array(
'Trailer.id !=' => $trailer_id
)
)
)
),
'conditions' => array(
'Industry.id' => $id
)
)
);
If I would specify 'limit' for 'Trailer', I get correct number of results but some null array for a movie which doesn't contain any trailers. Please help me to get the number of specified limit of trailers for particular industry. The work will be most appreciated.
It looks to me like you've got your contain key in the wrong place. It should be defined before the models.
<?php
$this->paginate = array(
'contain' => array(
'Industry' => array(
'Movie' => array(
'order' => 'Movie.release DESC',
'Trailer' => array(
'conditions' => array(
'Trailer.id !=' => $trailer_id
)
)
)
)
),
'conditions' => array(
'Industry.id' => $id
)
);

How do I get CakePHP 2.2.4 to contain and return data for 4th level association?

I have four models (Location->StatisticCategory->StatisticItem->Statistic) that I'm trying to return in a single query. The results are as expected until the query starts at the level of Location. At that point the data return contains everything down to the 3rd association in StatisticItem, but every single Statistic is null. Any idea why 4th level associations (at least here) are not returning any data?
Below is the code I'm using in my StatisticsController with Containable behavior turned on in AppModel:
$stats = $this->Location->find('all', array(
'fields' => array(
'Location.id',
'Location.location'
),
'conditions' => array(),
'recursive' => 2,
'contain' => array(
'StatisticCategory' => array(
'fields' => array(
'StatisticCategory.id',
'StatisticCategory.location_id',
'StatisticCategory.category'
),
'StatisticItem' => array(
'fields' => array(
'StatisticItem.id',
'StatisticItem.statistic_category_id',
'StatisticItem.item'
),
'Statistic' => array(
'fields' => array(
'Statistic.id',
'Statistic.statistic_item_id',
'Statistic.date',
'Statistic.number'
),
'conditions' => array(
'Statistic.date' => $date
)
),
'order' => array('StatisticItem.item')
),
'order' => array('StatisticCategory.category')
)
),
'order' => array('Location.location')
));
The documentation for containable describes how to contain deeper associations. The following should be about what you're looking for:
$this->Location->find('all', array(
'contain' => array(
'StatisticCategory' => array(
'StatisticItem' => array(
'Statistic'
)
)
)
));

Resources