$conditions = Array
(
[table] => products_pages
[alias] => ProductsPage
[type] => inner
[foreignKey] =>
[conditions] => Array
(
[0] => ProductsPage.product_id = Product.id
)
)
I'm trying to set up NOT EXISTS conditions, like the following SQL statement:
SELECT * FROM products_pages,products
WHERE NOT EXISTS (SELECT id
from products_pages
where products_pages.product_id = products.id)
So basically select any product that doesn't exist in the products_pages table.
What is the proper way to format that SQL statement for CakePHP and replace it here:
[conditions] => Array
(
[0] => (What's the proper way to insert above SQL here?
)
Would really appreciate your help guys, I've been trying to figure this out for about 5 hours with no luck. Thanks!
You can always use query if you don't find the way to do it with CakePHP:
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#model-query
In this case security wouldn't be compromised as you are not using any input.
Anyway, something simple would be just to do it in more than one step:
//selecting the products in the productcs_pages table
$productsWithPages = /* query to get them*/
//getting an array of IDs
$productsWidthPagesIds = Hash::extract($productsWithPages, '{n}.Product.id');
//doing the NOT IN to select products without pages
$productsWithoutPages= $this->Product->find('all',
array('conditions' =>
array( 'NOT' => array('Product.id' => $productsWidthPagesIds )
)
);
Related
If you get the following code :
$DBConnection =
CreateNewDBConnection(Yii::$app->get('db_cdh'),$aDatabaseName);
$DBConnection->open();
$command = $DBConnection->createCommand($aQuery);
$queryres = $command->queryAll();
If there is result from the query, I get an array, like this
Array
(
[0] => Array
(
[name] => 2.6.084.545
[xdim+2] => 70
)
[1] => Array
(
[name] => 2.5.102.030
[xdim+2] => 60
)
[2] => Array
(
[name] => 2.5.141.560
[xdim+2] => 80
)
)
But if the result of the query is empty, i get an empty array.
How is it possible to get the columns name ?
The reason why I'm asking this, it's because I'm asking queries to multiple DBs and some have results (1 or more lines) and otherd not. The system almost works, but the grid view parse only the first line to find the columns to display. So depending on the order result across the multiple DB, the grid view display the columns or not, depending what come first ....
Any help welcome.
You can take the column names using yii\db\TableSchema and use them afterwards:
$columns = [];
if (empty($queryres)) {
$columns = $DBConnection->getTableSchema('your_table_name')->getColumnNames();
}
I am using cakephp in one of my project. What i need is to handle complex query using single model and single array out.Since I am new to cakephp i got stucked really very bad here :
$rs = $this->User->query("
SELECT (wd.wajebaat_amt) as commited,
SUM(pd.sila_waje) as paid,
(wd.wajebaat_amt-sum(pd.sila_waje)) as balance,
FROM wajebaat_details as wd
LEFT JOIN waje_pay_details as pd ON (pd.waje_id=wd.waje_id)
WHERE wd.hof_id="123" and wd.year="2010"
GROUP BY wd.waje_id");
print_r($rs); exit();
// it displays output as
Array
(
[0] => Array
(
[wd] => Array
(
[commited] => 252000
)
[0] => Array
(
[paid] => 253829
[balance] => -1829
)
)
)
//however i need it following format
Array
(
[0] => Array
(
[wd] => Array
(
[commited] => 252000
[paid] => 200000
[balance] => 52000
)
)
)
You can use Hash (utility) method format() in cakephp 2.5 to convert the nested array into string,in previous version of cakephp the method is set(),
Hash::format(array $data, array $paths, $format)
Example :
$result = Hash::format($rs,array('{n}.wd.commited','{n}.wd.0.paid','{n}.wd.0.balance'),'%1$d,%2$d,%$d');
Output:
252000,2000000,52000
For More formating option refere cook book of cakephp
In cake php is how we can get order of query result according to 'IN' clause in the query
$array = array(8,6); // order in 'In' clause
$condition = array('Video.id' => $array);
$videos = $this->Video->find('all', array('conditions' => $conditions));
//The query will be like below
SELECT * FROM `videos` AS `Video` WHERE `Video`.`id` IN (8,6);
Currently it will give result as
Array
(
[0] => Array
(
[Video] => Array
(
[id] => 6
)
)
[1] => Array
(
[Video] => Array
(
[id] => 8
)
)
)
I need it like
Array
(
[0] => Array
(
[Video] => Array
(
[id] => 8
)
)
[1] => Array
(
[Video] => Array
(
[id] => 6
)
)
)
order Desc or asc will not retreive actual result in order. How it can retreved using cake php ?
I am using cake php, whether this can be done in mysql ?
ORDER is an option in CakePHP?
$this->Video->find('all', array('conditions' => $conditions, 'order' => array('Video.id DESC')));
In response to comment:
$this->Video->find('all', array('conditions' => $conditions, 'order' => array('FIELD(Video.id, 7, 4, 9)')));
ORDER BY FIELD("videos"."id",8,6)
i'm quote sure you can use it in cake's find
You can even use the ELT function in this way:
ORDER BY ELT(videos.id, 8,1,6,2,n,3,.....)
This works fine for me
$order = array("FIND_IN_SET(Video.id, '8,6')");
$result = $this->Video->find('all', array('conditions' => $conditions,'order' => $order);
SELECT * FROM table WHERE id IN (1,2,3,4,5)
The above query can be converted to CakePHP like so:
<?php
$ids = array(1,2,3,4,5);
$this->Model->find('all', array('conditions' => array('Model.id' => $ids)));
?>
Why not write
SELECT * FROM `videos` as `Videos` WHERE `Videos`.`id` IN (8,6) ORDER BY `Videos`.`id` DESC
It is not a best practice to use * in your SELECT statement.
Let me know if that helps.
EDIT
If needed we can also sort it using another method
Order By Case `Video`.`id`
When 8 Then 1
When 1 Then 2
When 3 Then 3
END
This query works:
SELECT Article.id,
Article.post_time,
Article.post_locked,
Article.comments_locked, Article.title,
IF(CHAR_LENGTH(Article.content)>2000,
RPAD(LEFT(Article.content,2000),2003,'.'),
Article.content) as content,
Article.tags, Category.*,
User.id, User.user_name,
Comment.comment_count
FROM `articles` as `Article`
LEFT JOIN `categories` as `Category` ON `Article`.`category_id` = `Category`.`id`
LEFT JOIN `users` as `User` ON `Article`.`user_id` = `User`.`id`
LEFT OUTER JOIN (SELECT article_id, count(*) comment_count FROM `comments`) as `Comment` ON `Article`.id = `Comment`.article_id
WHERE '1'='1'
ORDER BY `Article`.`id` DESC
But when I loop through the resultset to assign the table name along with the field using 'mysql_field_table', the 'content' returns a table name of nothing, while all others have their correct table:
Array (
[0] => Article
[1] => Article
[2] => Article
[3] => Article
[4] => Article
[5] =>
[6] => Article
[7] => Category
[8] => Category
[9] => User
[10] => User
[11] => Comment )
using
for ($i = 0; $i < $numOfFields; ++$i) {
array_push($table,mysql_field_table($this->_result, $i));
array_push($field,mysql_field_name($this->_result, $i));
}
Anyone ever try to do this? Have a solution? I want to return less data from my DB in my query. Or is it less intensive (on mysql, memory, cpu) to simply select all content and truncate the content via PHP? I thought returning less from DB would be better.
Thanks a bunch!!
Peace.
EDIT
to clear up, this is the result, you will see why it isnt what I want:
Array (
[0] => Array (
[Article] => Array (
[id] => 8
[post_time] => 1278606312
[post_locked] => 0
[comments_locked] => 0
[title] => Article 8
[tags] => test )
[] => Array (
[content] => my content for Article )
[Category] => Array (
[id] => 2
[name] => cat2 )
[User] => Array (
[id] => 3
[user_name] => user3 )
[Comment] => Array (
[comment_count] => 1 )
)
[1] => Array (
[Article] => Array (
[id] => 7
etc...
In order to use characters beyond the English alphabet and spaces in a column alias, the standard SQL means requires using double quotes (though MySQL supports using backticks IE: "`" too):
...,
IF(CHAR_LENGTH(Article.content)>2000,
RPAD(LEFT(Article.content,2000),2003,'.'),
Article.content) AS "Article.content",
...
no you cant use a as [tablename].[columnname]-like format for custom column names.
It would be weird anyway if it would work, because how can content be defined as 'Article.content' if it's not really part of the Article table dataset.
Just select the columns you need and join where needed.
But what's WHERE '1' = '1' doing in there? that will just evaluate to true as it is a boolean expression, but it won't affect your resultset.
But when I loop through the resultset
to assign the table name along with
the field using 'mysql_field_table',
the 'content' returns a table name of
nothing, while all others have their
correct table
Once you've done that magic on Article.content, to create the content field, it no longer belongs to the Article table. Rather, it belongs to the result set of that query. I believe that's the explanation for having no table associated with that field.
Imagine a GROUP BY query, with something like COUNT(*) as number. 'number' doesn't belong to any table.
If you really need the ability to know that the column had a particular source, could you have a view on top of Article which does this manipulation to content? Then the source would appear to be the view? Unfortunately, MySQL doesn't support declared computed columns in tables, that might also be useful to you in this case.
while ($row = mysql_fetch_row($this->_result)) {
$prev_table;
for ($i = 0;$i < $numOfFields; ++$i) {
if ($table[$i] == "") {
$tempResults[$prev_table][$field[$i]] = $row[$i];
}else {
$tempResults[$table[$i]][$field[$i]] = $row[$i];
}
$prev_table = $table[$i];
}
}
Oh well, mysql couldnt do what I wanted. I added the prev_table to take the one before ;)
Thanks to everyone for the help.
I have 2 tables in my db...
Entita
id int(11)
descrizione varchar(50)
.....
Publicobjects
....
model varchar(50) the model I need (in this case 'Entita')
model_id int(11)
I would like to make a query like this:
select entita.*
from entita
where NOT EXISTS (select * from publicobjects where publicobjects.model = 'Entita' and publicobjects.model_id = entita.id)
How can I do this with the model functions of Cakephp without use custom query?
Thanks
I believe you're trying to find rows from the Entita table that are not in the Publicobjects table. Assuming that is correct, here is the SQL query for MySQL to find it:
SELECT `entita`.*
FROM `entita`
LEFT JOIN `publicobjects` ON (`publicobjects`.`model` = 'entita'
AND `publicobjects`.`model_id` = `entita`.`id`)
WHERE `publicobjects`.`model_id` IS NULL
To make this work with CakePHP's models takes a couple of steps. I've made some assumptions about your model names, but I could be wrong and those are easy to fix.
First add this to the Entita model:
<?php
var $hasOne = array('Publicobject' => array(
'foreignKey' => 'model_id',
'conditions' => 'Publicobject.model = "Entita"'));
Now, you can check for entries that are missing in the Publicobjects table like this:
<?php
$this->Entita->find('all', array('conditions' => array('Publicobject.model_id IS NULL')));