I want something like this:
$res = Model::find('all', array(
'fields' => array(
'SUM(col1)' => array(
'alias' => 'col1_total',
),
'SUM(col2)' => array(
'alias' => 'col2_total',
)
)
);
expected generated SQL:
SELECT SUM(col1) AS col1_total, SUM(col2) AS col2_total
FROM `tbl` AS `Model` WHERE 1;
I tried many ways.
is this possible?
a working example for a single col:
$res = Model::find('all', array(
'fields' => 'SUM(col1)'
)
);
Cool!
working example:
$res = Model::find('all', array(
'fields' => array(
'SUM(col1) AS col1_total',
'SUM(col2) AS col2_total'
)
);
Related
I want to make a select that solves the fact that I have to perform two validations one for each table, what i'm doing now is validating the $table1 and validating the $table2 ,i just want to validate $table2
$table1 = DB::table('name_table1')
->where('invoice_id','{$table2}.id')
->get();
$table2 = DB::table('name_table2')
->select('name','invoices','{$table} as itens_of_invoice')
->get();
dd($table);
And return me something like;
Array (
[0] => Object(
'name' => 'value_name',
'invoices' => 'value_invoices',
'item_of_invoice' =>
Array(
[0] => Array(
'name_item' => 'value_name',
'price' => 'value_price'
)
)
)
[1] => Object(
'name' => 'value_name',
'invoices' => 'value_invoices',
'item_of_invoice' =>
Array(
[0] => Array(
'name_item' => 'value_name',
'price' => 'value_price'
)
)
)
[2] => Object(
'name' => 'value_name',
'invoices' => 'value_invoices',
'item_of_invoice' =>
Array(
[0] => Array(
'name_item' => 'value_name',
'price' => 'value_price'
)
)
)
)
I don't find any solution if someone ever did this please help me
This code:
$conditions = array(
'fields' => array(
'User.id'
),
'conditions' => array(
'AND' => array(
'UsersProblem.problem_id' => 38,
'UsersProblem.problem_id' => 34,
),
),
'recursive' => -1
);
$conditions['joins'][] = array(
'table' => 'users_problems',
'alias' => 'UsersProblem',
'type' => 'INNER',
'conditions' => array(
'User.id = UsersProblem.user_id',
));
Is transforming to this SQL query:
SELECT `User`.`id`
FROM `lawyers`.`users`
AS `User`
INNER JOIN `lawyers`.`users_problems`
AS `UsersProblem`
ON (`User`.`id` = `UsersProblem`.`user_id`)
WHERE `UsersProblem`.`problem_id` = 34
Where is AND UsersProblem.problem_id = 38"?
How to create correct find condition to get users with some list of problems? Which are linked as many to many relationship.
Using $this->Problem->find is not possible, beause I need to use 2 joins: users_problems and users_practices. And use for them AND condition, like this:
'AND' => array(
'UsersProblem.problem_id' => 38,
'UsersProblem.problem_id' => 34,
'UsersPractices.practice_id' => 1,
'UsersPractices.practice_id' => 2,
),
You're overwriting 'UsersProblem.problem_id'. Just think about it like the array it is. CakePHP is just using the PHP array structure to do these finds, and that means it follows array rules. But to get around that in cakephp, you're supposed to use a two dimensional array
Like this:
'AND' => array(
array('UsersProblem.problem_id' => 38),
array('UsersProblem.problem_id' => 34)
),
Instead of this:
'AND' => array(
'UsersProblem.problem_id' => 38,
'UsersProblem.problem_id' => 34
),
That way, instead of trying to set the key 'UsersProblem.problem_id' twice, you're making an array that looks like
0 -> array('UsersProblem.problem_id' => 38)
1 -> array('UsersProblem.problem_id' => 34)
And that will work, it's a workaround the CakePHP guys built into the system for this kind of situation.
I think you need to use OR instead of AND:
$conditions = array(
'fields' => array(
'User.id'
),
'conditions' => array(
'OR' => array(
array('UsersProblem.problem_id' => 38),
array('UsersProblem.problem_id' => 34),
),
),
'recursive' => -1
);
You can also roll this up as follows:
$conditions = array(
'fields' => array(
'User.id'
),
'conditions' => array(
'OR' => array(
'UsersProblem.problem_id' => array(34, 38)
),
'recursive' => -1
);
Change your conditions array as shown below:
$options = array(
'fields' => array('User.id'),
'conditions' => array('UsersProblem.problem_id' => array(38,34)),
'recursive' => -1
);
$options['joins'] = array(
array(
'table' => 'users_practices',
'alias' => 'UsersPractices',
'type' => 'INNER',
'conditions' => array(
/CONDITION OF JOIN/
),
array(
'table' => 'users_problems',
'alias' => 'UsersProblem',
'type' => 'INNER',
'conditions' => array(
'User.id = UsersProblem.user_id',
)
);
From User Model:
$this->find('list',$options);
Do not use AND/ OR because they are not optimized for above case.
For reference:
MYSQL OR vs IN performance
and
CakePHP right way to do this (get value from setting's table)
**Try the code for join tables in cakephp.......**
$options = array('joins' => array(
array(
'table' => 'modelname1',
'alias' => 'modelName1',
'type' => 'LEFT',
'foreignKey' => false,
'conditions' => array('modelname1.id = modelname2.mid')
)
),
'fields' => array('modelName1.field1', 'modelName1.field2', 'modelName2.field1', 'modelName2.field2'),
'conditions' => array('modelname.id' => 1, 'modelname2.field1' => ''),
'limit' => 10, 'page' => 1);
$this->modelName2->find($options);
i am working on a cakephp and try to implement the join . or inner join query ... what i am doing right now is this
$this->bindModel(array(
'belongsTo' => array(
'Contact' => array(
'className' => 'Contact',
'foreignKey' => false,
'conditions' => array(
'Message.user_id = Contact.user_id',
'Message.mobileNo = Contact.mobileNo'
)
)
)
), false);
return $message_details = $this->find('all', array(
'conditions' => array(),
'fields' => array('DISTINCT mobileNo')
));
this query is doing LEFT JOIN the table .. what i want is join or inner join between two tables
You can specify the type of join in your belongsTo configuration, as stated in the documentation. The default is left, but you can use any valid join type. Simply add 'type' => 'inner' to the configuration array, so you should get something like this:
$this->bindModel(array(
'belongsTo' => array(
'Contact' => array(
'className' => 'Contact',
'foreignKey' => false,
'conditions' => array(
'Message.user_id = Contact.user_id',
'Message.mobileNo = Contact.mobileNo'
),
'type' => 'inner' // Simply add this
)
)
), false);
Alternatively, you can add the joins to your query without using bingModel:
return $message_details = $this->find('all', array(
'conditions' => array(),
'fields' => array('DISTINCT mobileNo'),
'joins'=>array(
array(
'table'=>'contacts,
'alias'=>'Contact',
'type'=>'INNER',
'conditions'=>array(
'Message.user_id = Contact.user_id',
'Message.mobileNo = Contact.mobileNo'
)
)
)
));
Presume the Query works:
SELECT
users.id,
subscriptions.name,
users.user_type
FROM users
LEFT JOIN users_subscriptions
ON users.id = users_subscriptions.user_id
LEFT JOIN subscriptions
ON users_subscriptions.subscription_id = subscriptions.id
WHERE
subscriptions.name = 'advertisers'
AND
users.user_type = 'agent';
How do I do this in a single Query using cakePHP 1.3?
EDIT: Are joins the right approach?
Yes joins are just fine. Just make sure that you add on the fly before searching to your User model a hasOne to UsersSubscription and to the UsersSubscription model as belongsTo Subscription. Then use the containable behavior to include 'UserSubscription' => 'Susbcription'
Your code might look like this:
$this->User->bindModel(array('hasOne' => array('UserSubscription')));
$this->User->UserSubscription->bindModel(array('belongsTo' => array('Subscription')));
$results = $this->User->find('all', array(
'contain' => array(
'UserSubscription' => 'Subscription'
)
));
You can set up the query the "CakePHP way" like this:
$conditions = array(
'Subscriptions.name' => 'advertisers',
'Users.user_type' => 'agent'
);
$joins = array(
array(
'table' => 'users_subscriptions',
'alias' => 'UsersSubscriptions',
'type' => 'LEFT',
'conditions' => array(
'UsersSubscriptions.user_id=Users.id'
)
),
array(
'table' => 'subscriptions',
'alias' => 'Subscriptions',
'type' => 'LEFT',
'conditions' => array(
'Subscriptions.id=UsersSubscriptions.subscription_id'
)
)
);
$fields = array(
'Users.id', 'Users.user_type', 'Subscriptions.name'
);
$options = array(
'conditions' => $conditions,
'joins' => $joins,
'fields' => $fields
);
$results = $this->Users->find('all', $options);
I want to reduce the number of fields returned by cakephp's find('all') but don't know if this is possible.
$this->Group->find('all', $params);
where $params
$params = array(
'conditions' => array(
'Group.featured' => 1,
),
'contain' => array(
'User',
'Class' => array(
'conditions' => array(
'Class.exp IS NOT NULL',
'Class.tb <20',
)
)
)
));
The problem is that my Class table has many columns that i don't need and that take a long time to load, so i would line to only select 5 fields.
Can this be done in Cakephp or am i better off writing a regular query?
something like
$params = array(
'conditions' => array(
'Group.featured' => 1,
),
'contain' => array(
'User',
'Class.a',
'Class.b',
'Class.exp',
'Class.tb',
'Class' => array(
'conditions' => array(
'Class.exp IS NOT NULL',
'Class.tb <20',
)
)
)
));
Thank you
That's what the fields parameter is for.
$params = array(
...
'contain' => array(
'Class' => array(
'conditions' => array(
'Class.exp IS NOT NULL',
'Class.tb <20',
),
'fields' => array('a', 'b')
)
)
);