I'm writing some Database queries with Propel(symfony), but propel always add some query!
For example :
SELECT COUNT(*) FROM table WHERE (table.start>='2012-06-01 00:00:00'
AND table.end<='2012-06-30 00:00:00') AND table.deleteat IS NOT NULL
The Propel always add the : AND table.deleteat IS NULL
Can i remove that?
Thank you for the Idea #j0k
In my schema.yml i saw that there exist a soft_delete. For the next Query just disable it with : BookQuery::disableSoftDelete(); link
Related
I'm executing a PHP yii2 query to get records from the database but it's not working. But I directly executed the query in the MYSQL console then it gives me the expected output.
Normal SQL
SELECT * FROM `tbl_inbox` WHERE sender_id=778 AND recipient_id=736 OR sender_id=778 AND recipient_id=736 ORDER BY timestamp DESC LIMIT 1
Above query giving me expected result but when i change to Yii2 like :
$message=Inbox::find()->select(['message'])->where(['sender_id'=>$sender_id,'recipient_id'=>$recipient_id])->orWhere(['sender_id'=>$recipient_id,'recipient_id'=>$sender_id])->andWhere(['ad_id'=>$ad_id,'category'=>$category])->orderBy(['timestamp'=>SORT_DESC])->one();
It gives me the wrong result.
What is my logic :
I have a chat on my website and I need to get the last message order by timestamp. But sender_id and the recipient will be visa versa.
How to fix ?
There are significant differences between the normal SQL version of the query and the Yii version.
1) Selected fields
The normal SQL query selects all fields, but Yii version selects only message field.
This is because the normal SQL has SELECT * FROM ... but in Yii query you are calling select(['message']). If you want to select all fields you can leave the select() method call out or you can use select('*').
2) Your conditions are different
Considering operator priority your conditions in normal SQL are:
(sender_id=778 AND recipient_id=736)
OR (sender_id=778 AND recipient_id=736)
But in your Yii version of query:
(
(sender_id=778 AND recipient_id=736)
OR (sender_id=736 AND recipient_id=778)
) AND (
ad_id=$ad_id AND category=$category
)
In your normal SQL the both sides of OR condition are same but in your Yii version the values for sender/recipient are swapped in the second argument of OR operator.
Also there is extra part added by this call andWhere(['ad_id'=>$ad_id,'category'=>$category])
$message=Inbox::find()->select(['message'])->where(['sender_id'=>$sender_id,'recipient_id'=>$recipient_id])->orWhere(['sender_id'=>$recipient_id])->orWhere(['recipient_id'=>$sender_id])->andWhere(['ad_id'=>$ad_id,'category'=>$category])->orderBy(['timestamp'=>SORT_DESC])->one();
try this
I'm getting following sql
SELECT `message` FROM `user` WHERE ((((`sender_id`='2333') AND (`recipient_id`='23222')) OR (`sender_id`='23222')) OR (`recipient_id`='23333')) AND ((`ad_id`='10') AND (`category`='1')) ORDER BY `timestamp` DESC
you can check raw sql easily, then it will be mostly straight forward how Yii Query builder works.
use following code:
$rawSql = Inbox::find()
...
->createCommand()->getRawSql();
I would change your code into this:
$message=Inbox::find()
->select(['message'])
->where([
'and',
[
'or',
['sender_id'=>$sender_id,'recipient_id'=>$recipient_id],
['sender_id'=>$recipient_id,'recipient_id'=>$sender_id]
],
['ad_id'=>$ad_id,'category'=>$category]
])
->orderBy(['timestamp'=>SORT_DESC])->one();
I'd like to make union query with Laravel Eloquent.
When we proceed UNION queries, there should be the same number of selected columns in both queries.
To skip that rule I would like to select NULL as Column_name,
but Laravel API automatically replaces NULL with 'Null' and that causes an error "Null column is not existed".
How to remove these automatically added quotes from Null?
That is what I have:
The first query:
...->select("Calendars.*","Services.Id as IdService","Services.Name as ServiceName","NULL as Price")
The second query:
...->select("Calendars.*","Services.Id as IdService","Services.Name as ServiceName","PaidService.Price")
Result is:
...union (select `Calendars`.*, `Services`.`Id` as `IdService`, `Services`.`Name` as `ServiceName`, `NULL` as `Price` from `Calendars`
Thanks a lot!
Consider using DB::raw for this. It will stop laravel from modifying the statement and parse it as is.
DB::raw("NULL as Price")
which will make the first query
...->select("Calendars.*",
"Services.Id as IdService",
"Services.Name as ServiceName",
DB::raw("NULL as Price"))
I want to make php code with SQL Update Statement in Codeigniter.
If I execution code in Codeigniter, the data in database will be updated too.
I want to update one column (ID_STATUS) but with several condition.
The connection column 'ID_STATUS' with column 'lama' and 'estimasi'
My table name is "pelayanan".
ID_STATUS is PK from table "status".
So, Column ID_STATUS in table "pelayanan" is foreign key from table "status".
I tried with this query, but, It isn't if else condition yet.
condition 1 :
UPDATE `dbhpl`.`pelayanan`
SET `pelayanan`.`ID_STATUS` = '1'
WHERE `pelayanan`.`LAMA` <> `pelayanan`.`ESTIMASI`;
condition 2:
UPDATE `dbhpl`.`pelayanan`
SET `pelayanan`.`ID_STATUS` = '2'
WHERE `pelayanan`.`LAMA` = `pelayanan`.`ESTIMASI`;
That is the query on mysql. But I want to convert that query to php code (Codeigniter).
How come It will be?
your first query is
UPDATE `dbhpl`.`pelayanan`
SET `pelayanan`.`ID_STATUS` = '1'
WHERE `pelayanan`.`LAMA` <> `pelayanan`.`ESTIMASI`;
convert it as follows:
$update_data=array('ID_STATUS'=>'1');
$this->db->where('LAMA <>','ESTIMASI');
$this->db->update('pelayanan',$update_data);
your second query is
UPDATE `dbhpl`.`pelayanan`
SET `pelayanan`.`ID_STATUS` = '2'
WHERE `pelayanan`.`LAMA` = `pelayanan`.`ESTIMASI`;
convert it as follows:
$update_data=array('ID_STATUS'=>'2');
$this->db->where('LAMA','ESTIMASI');
$this->db->update('pelayanan',$update_data);
I have remove database name. database name will be selected in connection and and did required to mentioned it here.
condition 3:
a. both LAMA and ESTIMASI are null.
b. LAMA is null
c. ESTIMASI is null
If you want to update all rows in the table, based on the values of LAMA and ESTIMASI, you could do that in one fell swoop with one UPDATE statement.
UPDATE `dbhpl`.`pelayanan` p
SET p.`ID_STATUS`
= CASE
WHEN p.`LAMA` = p.`ESTIMASI` THEN '2'
WHEN p.`LAMA` <> p.`ESTIMASI` THEN '1'
WHEN p.`LAMA` IS NULL AND p.`ESTIMASI` IS NULL THEN p.`ID_STATUS`
WHEN p.`LAMA` IS NULL THEN p.`ID_STATUS`
ELSE p.`ID_STATUS`
END
Note that assigning the current value of the ID_STATUS column back to the ID_STATUS column results in "no update".
Since the last two WHEN conditions return the same values as the ELSE, those could be removed. These were included just to illustrate possible handling of condition 3.
One small difference with this vs. the original is that it will attempt tto update every row in the table, including rows that have a NULL value in LAMA and/or ESTIMASI. That means any UPDATE triggers will be fired for those rows. To get exactly the same result as the original, you'd need to include a WHERE clause that excludes rows where LAMA is null or ESTIMASI is null. For example:
WHERE p.`LAMA` IS NOT NULL
AND p.`ESTIMASI` IS NOT NULL
As far as how to accomplish this same thing in PHP, someone else may be able to answer that. Personally, I'd just do it one SQL operation.
The ANSI-standard syntax is a bit verbose. A MySQL specific version that accomplishes the same thing is a bit shorter:
UPDATE `dbhpl`.`pelayanan` p
SET p.`ID_STATUS` = IFNULL((p.`LAMA`=p.`ESTIMASI`)+1,p.`ID_STATUS`)
FOLLOWUP
If LAMA and ESTIMASI are defined as NOT NULL, then you wouldn't have to deal with condition 3. (In the more general case, we don't necessarily have that guarantee, so I think it's better pattern to account for those conditions, even if they won't ever happen in our particular case.
For CodeIgniter ActiveRecord, you'd could try something like this:
$this->db
->set('ID_STATUS', 'IFNULL((`LAMA`=`ESTIMASI`)+1,`ID_STATUS`)', FALSE)
->update('`dbhpl`.`pelayanan`');
I need to write a update query in a model which use tablegateway. The update query sql like following.
UPDATE `config_settings` SET `CS_value` = CASE `CS_option`
WHEN 'CATEGORY_BANNER_MIN_WIDTH' THEN '$data->CATEGORY_BANNER_MIN_WIDTH'
WHEN 'CATEGORY_BANNER_MAX_WIDTH' THEN '$data->CATEGORY_BANNER_MAX_WIDTH'
WHEN 'CATEGORY_PROMOTION_MIN_WIDTH' THEN '$data->CATEGORY_PROMOTION_MIN_WIDTH'
WHEN 'CATEGORY_PROMOTION_MAX_WIDTH' THEN '$data->CATEGORY_PROMOTION_MAX_WIDTH'
WHEN 'PRODUCT_LARGE_IMAGE_WIDTH' THEN '$data->PRODUCT_LARGE_IMAGE_WIDTH'
WHEN 'PRODUCT_MEDIUM_IMAGE_WIDTH' THEN '$data->PRODUCT_MEDIUM_IMAGE_WIDTH'
WHEN 'PRODUCT_SMALL_IMAGE_WIDTH' THEN '$data->PRODUCT_SMALL_IMAGE_WIDTH'
ELSE `CS_value`
END;
I have no idea how to implement this. The update method of tablegateway only take array of table field name and its value. So how to write this query.
I know that i can execute this query using db adapter raw sql query but i don't want this. Beside this, some times we need to some custom query in select method of tablegateway. But i found no stable way in tablegateway.
For example:
select sum(CASE WHEN answers.type = 'his' THEN 1 ELSE 3 END) AS totalScore
FROM users_questions_answers join answers on cast(answers.id as int(8))=
users_questions_answers.answer_id group by users_questions_answers.user_id
How can i proceed in this situation. Any zend 2 expert suggestion will highly appreciated.
Thanks for your kind consideration.
Try this -
$this->tablegateway->update(array('CS_value' => new \Zend\Db\Sql\Expression('CASE CS_option
WHEN "CATEGORY_BANNER_MIN_WIDTH" THEN ?
WHEN "CATEGORY_BANNER_MAX_WIDTH" THEN ?
WHEN "CATEGORY_PROMOTION_MIN_WIDTH" THEN ?
WHEN "CATEGORY_PROMOTION_MAX_WIDTH" THEN ?
WHEN "PRODUCT_LARGE_IMAGE_WIDTH" THEN ?
WHEN "PRODUCT_MEDIUM_IMAGE_WIDTH" THEN ?
WHEN "PRODUCT_SMALL_IMAGE_WIDTH" THEN ?
ELSE CS_value END',
array($data->CATEGORY_BANNER_MIN_WIDTH, $data->CATEGORY_BANNER_MAX_WIDTH, $data->CATEGORY_PROMOTION_MIN_WIDTH, $data->CATEGORY_PROMOTION_MAX_WIDTH, $data->PRODUCT_LARGE_IMAGE_WIDTH, $data->PRODUCT_MEDIUM_IMAGE_WIDTH, $data->PRODUCT_SMALL_IMAGE_WIDTH))));
If CATEGORY_BANNER_MIN_WIDTH like used in the query are some constants then just remove the double quotes around it.
I have tried a similar query to the above one and it works just fine.
I´d like to add an extra column to the select for formatting purposes. The problem is that when I do
$this->db->select("NULL as ExtraColumn1")
codeigniter treats NULL as a column, so when it generates the query it's something like
SELECT `NULL` AS ExtraColumn1 ...
which of course returns a DB error. The same happens when I try
$this->db->select(" '' as ExtraColumn1")
Is there any way of doing it using activerecord?
Thanks
Tell CodeIgniter not to wrap fields in ticks. You do this by passing false as the second parameter in select():
$this->db->select("NULL as ExtraColumn1", false);
From the manual:
$this->db->select() accepts an optional second parameter. If you set it to FALSE, CodeIgniter will not try to protect your field or table names with backticks. This is useful if you need a compound select statement.