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"))
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();
If i give hard coded value inside query it works, but not in case of sub query or column given.
Here is small example of issue i am facing :
Following both query is a type of sub query, like its part of another query, so don't think that where is table 'm' and something else, as it is working already.
So, my query like :
1)
SELECT GROUP_CONCAT(CONCAT(a_u.first_name,' ', a_u.last_name)) AS associated_admin_u
FROM users a_u
WHERE a_u.id IN(m.associated_admin)
GROUP
BY m.id
And m.associated_admin will return a quoted string like '1,10' so this will not work because of its a string.
2)
SELECT GROUP_CONCAT(CONCAT(a_u.first_name,' ', a_u.last_name)) AS associated_admin_u
FROM users a_u
WHERE a_u.id IN(1,10)
GROUP
BY m.id
If i write hard code like 1,10 it works, because it is not a string
So first one is not works because that query is part of another query as a sub query.
And i am sure this question couldn't be duplicate as i am facing it like in this way so any help would be appreciate, thanks reader!
Based on your comments, you need something like:
SELECT GROUP_CONCAT(CONCAT(a_u.first_name,' ', a_u.last_name)) AS associated_admin_u
FROM users a_u
WHERE FIND_IN_SET(a_u.id, TRIM(BOTH '\'' FROM m.associated_admin))
GROUP
BY m.id
This will first trim the quotes from m.associated_admin and then use FIND_IN_SET instead of IN so that you can use a string with comma-separated values.
You can just create a subquery in IN for example:
SELECT group_concat(CONCAT(a_u.first_name,' ', a_u.last_name)) AS associated_admin_u
FROM users a_u WHERE a_u.id IN(
SELECT id FROM mytable WHERE id IN(1,10)
) GROUP BY m.id
I am trying to set a column result literal with the Laravel query builder. By writing raw SQL I would achieve this with:
SELECT
`field1`,
`field2`,
'Test' AS `field3`
FROM `Test`;
Therefore MySQL will always return Test for column field3. I'm trying to do this with the query builder like select('field1', 'field2', '"Test" AS field3') but this doesn't seem to work. It will return an error that Test is not a column name.
Does anyone have an idea how I could do this?
You want the DB::raw() function:
->select('field1', 'field2', DB::raw("'Test' AS field3"))
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.
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