For a search query I have the following:
DB::whereRaw('column = ?', 'foo')->orWhereRaw('column IS NULL')->get();
Adding the orWhereRaw statement gives me less results than only the whereRaw. Somehow it seems to ignore the first when adding the other. It is included in the SQL statement. Is there another way to compare for a string and null value?
I have also tried the following, as suggested below:
return self::select('id')
->where('current_state', 'unavailable')
->orWhereNull('current_state')
->get();
If I change the order (the whereNull first and the where second) this also gives me different results. It appears as if the inclusive query doesn't function correctly in correspondence with the where clause. If I use to regular where clauses I don't experience any issues.
Running SELECT * FROM events WHERE current_state='unavailable' OR current_state IS NULL; does produce the correct result for me.
Don't use whereRaw to check for null. You can use this instead:
->orWhereNull('column')
The proper way to do the first where, unless you're doing something extra such as a mysql function, is just to pass the column along like this:
where('column', '=', 'foo')
You can actually eliminate the equals, since it defaults to that. So your query would be:
DB::table('table')->where('column', 'foo')->orWhereNull('column')->get();
Related
I want to get the null expiry date result. My whereRaw is working fine but when I used orWhereNull, I get an error. Here is my code:
$offer_details = #\App\Offer::where('store_id',$store_id)->whereRaw('expiry_date > now()')->orWhereNull('expiry_date ')->get();
Following query should work for you as, I don't thing 'orWhereNull()' available in laravel :
$offer_details = #\App\Offer::where('store_id',$store_id)->
->whereNull('expiry_date')
->orWhereRaw('expiry_date > now()')
->get();
Unlike that the "or" variant of 'whereRaw()' is availble as 'orWhereRaw()'.
More details of : whereRaw / orWhereRaw
The whereRaw and orWhereRaw methods can be used to inject a raw where clause into your query. WhereRaw() is a function of Laravel query builder which puts your input as it is in the SQL query's where clause.
I am using Laravel
Let's say, I have two date fields in my table. If I want to compare them, i can do whereRaw clause.
$query->whereRaw('date1 > date2')->get()
Is there a way to make a modification to date2 inside this query, so it is actually date2-1day?
Something like:
$query->whereRaw('date1 > (date2-1day)')->get()
You are free to call any SQL code in the "raw" part of your query, so you could do sth like below:
$query->whereRaw('date1 > DATE_SUB(date2, INTERVAL 1 DAY)')->get();
Keep in mind that executing SQL code this way will make your queries work only in databases that support such functions.
Another way would be using whereColumn like
$users = DB::table('users')
->whereColumn('updated_at', '>', 'created_at')
->get();
OR
UserTable::whereRaw('column1 != column2')->get();
I tried to get results from my database using SQL but my results do not agree with what i am using as input. I always gets results from those who contains both integers and characters. For example, if i search for "liu" i get a result of "2LK020". I neither cant search with integers and get a correct result... I use:
$result = queryDatabase(
"SELECT course_tag, course_name FROM course WHERE course_tag OR course_name LIKE ?",
array(1 => '%' .$parameters[0]. '%')
is there a problem using "%"? or why do i get this weird answers?
Read this: http://dev.mysql.com/doc/refman/5.7/en/operator-precedence.html
You're doing the equivalent of
WHERE course_tag OR (course_name LIKE ?)
which comes to
WHERE true/false OR true/false
As long as course_tag isn't an empty string or a null or other "falsey" value, it'll pretty much always evaluate to a true value, and make the entire WHERE clause evaluate to true.
You can't test multiple fields against a single LIKE value. That simply doesn't work. You need to test each one individually:
WHERE (course_tag LIKE ?) OR (course_name LIKE ?)
However, since you're doing a %...% double-wild card search, you could optimize a bit with
WHERE CONCAT(course_tag, course_name) LIKE ?
I have this strange situation and not sure of what is wrong. I have a simple self join to find matches based on some conditions. I have this query running fine in mysql but when I call it through PHP, it doesn't return any values.
select * from Requests p inner join Requests c on c.ID<>p.ID
where usr_ID<>4
and p.c_ID = c.c_ID
This works fine but not the below one.
DB::table('Requests as parent')
->join('Requests as child', 'parent.ID', '<>', 'child.ID')
->where('parent.usr_ID', '<>', 4)
**->where('parent.c_ID', '=', 'child.c_ID')**
->get();
In the above query, if I remove the second where condition(c_ID), it returns correct values. For all rows, this has a value of 1. If I replace child.c_ID or parent.c_ID by 1, it works again. I have tried with other columns as well and found the same issue.
Any pointers?
What the query builder makes out of your second where condition is:
WHERE parent.c_ID = 'child.c_ID'
So instead of a "normal" where() use whereRaw(), which takes your input and injects it right into the final SQL query
->whereRaw('parent.c_ID = child.c_ID')
Alternatively you could also use DB::raw() on the third argument
->where('parent.c_ID', '=', DB::raw('child.c_ID'))
Both are essentially the same so use whichever you like more.
I wrote an active record query in CodeIgniter and then I realised that I needed to use OR with to WHERE clauses. So I looked through the docs and found or_where which did what I wanted. But when I use it it produces AND in the output. I couldn't find any other questions on this issue.
I'm using CodeIgniter: 2.1.0
Here is my code (slightly cut down):
$this->db->select("p.*",false);
$this->db->from('projects p');
$this->db->join('customers c', 'p.c_id = c.c_id','left outer');
if(isset($options['add_root']))
$this->db->or_where('p.p_id=',1,FALSE);
//Get top level projects by default (1) or whatever parent is specified.
if(isset($options['p_id']))
$this->db->where('p.p_id=',$options['p_id'],false);
$query = $this->db->get();//query
I don't think you need or_where. I think you need better if/else in PHP.
The logic you probably want:
if(isset($options['p_id']))
{
// if p_id is set, then look for p_id
$this->db->where('p.p_id=',$options['p_id'],false);
// if p_id and add_root are set, then look for p_id OR p_id = 1
if(isset($options['add_root']))
$this->db->or_where('p.p_id=',1,FALSE);
}
elseif(isset($options['add_root']))
{
// look for p_id = 1 only
$this->db->where('p.p_id=',1,FALSE);
}
Because or_where is first it is simply defaulting to where, and then the subsequent where is the default: an "and".
You could also write the above with a series of elseif's but I view this as less clear:
if(isset($options['p_id']) && isset($options['add_root']))
$this->db
->where('p.p_id=',$options['p_id'],false)
->or_where('p.p_id=',1,FALSE);
elseif(isset($options['p_id']) || isset($options['add_root']))
$this->db
->where('p.p_id=',
// if add_root is set, then 1, otherwise p_id
(isset($options['add_root'])?1:$options['p_id']),false);
There's a small error in the order of the query that you're trying to run. You can add multiple 'where' clause which will get converted to a query with an 'AND' in between. But if you wanna use 'OR' instead you use a 'or_where'.
In your query you've used an 'or_where' clause, which is correct but you've used 'where' after that, which literally adds up to the previous query. So, you gotta use the 'where' clause first and then use the 'or_where' clause.
Just change the order and it would work.