22

I have something like $user->albums()->where('col', NULL), it works fine then I tried to extend it to empty strings with $user->albums()->where('col', NULL)->or_where('col', '') and it's not working.

Also I saw on this post that I could use where_null('col') but it's not working and it's not documented. Any simple method to select where empty or NULL col

Daryn
  • 4,791
  • 4
  • 39
  • 52
Jonathan de M.
  • 9,721
  • 8
  • 47
  • 72

6 Answers6

66

Try using orWhereNull for the second clause:

$users = DB::table('users')
        ->where('col', '=', '')
        ->orWhereNull('col')
        ->get();

Or if you have multiple conditions in the query, you have to wrap the two in a closure:

    $users = DB::table('users')
             ->where(function(\Illuminate\Database\Eloquent\Builder $query) {
                $query->where('col', '')->orWhereNull('col');
            })
            ->where('col2','val2')
            ->get();


raveren
  • 17,799
  • 12
  • 70
  • 83
Jon
  • 2,277
  • 2
  • 23
  • 33
  • 5
    How would we change the where function incase if we have multiple conditions ? – Nevermore Jan 02 '17 at 07:45
  • 5
    @Nevermore Use a closure: `DB::table('users')->where(function($query) { $query->where(...)->orWhere(...)->orWhere(...); })->where(...)->where(...)->get();`. This will encapsulate the closure based conditions within parentheses in the rendered SQL. – Soulriser Mar 23 '18 at 19:27
  • 1
    Adding a model scope method can make using closures easier: usage: $model->whereIsEmpty($column1)->whereIsEmpty($column2); implementation: public function scopeWhereIsEmpty($query, $column) { return $query->where( function ($query) use ($column) { $query->where($column, '')->orWhereNull($column); } ); } – Jarrett Barnett Dec 10 '19 at 20:46
3

How about this:

$user->albums()->whereRaw("NOT col > ''")

This way you can check both conditions at the same time

1

Try this query:

$users = DB::table('users')
        ->whereRaw('col = "" OR col IS NULL')
        ->get();
Yasin Patel
  • 5,624
  • 8
  • 31
  • 53
1

I always encourage to create queries with the main Laravel functions that are most used. That's why you must have 2 things in mind:

  • algorithm. key1 = value1 AND key2 = value2 OR key3 = value3. Be very carreful about precedence because in the way I exemplified there will be a main OR not an AND with OR inside
  • using where(), whereIn(), whereNull and closure instead of whereRaw(). whereRaw is using more memory than any others I mentioned.

So, to resume your answer:

OR condition

$users = DB::table('users')
        ->where('col', '=', '')
        ->orWhere('col','=','')
        ->whereNull('col')
        ->get();

AND and OR condition

$users = DB::table('users')
->where(function($query) { $query->where('col','=','')->orWhere('col','=','')->whereNull('col'); })
->where('col','=','')
->get();
1

The below solution is tested on LARAVEL 9. Solution is to add to the App\Providers\AppServiceProvider this piece of code:

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        ///...
        Builder::macro('whereNullOrEmpty', function ($field) {
            return $this->where(function ($query) use ($field) {
                return $query->where($field, '=', null)->orWhere($field, '=', '');
            });
        });

        Builder::macro('whereNotNullOrEmpty', function ($field) {
            return $this->where(function ($query) use ($field) {
                return $query->where($field, '<>', null)->where($field, '<>', '');
            });
        });
    }
    //...
}

and then call it like this:

if($nullOrEmpty){
    $builder->whereNullOrEmpty('col');
}else{
    $builder->whereNotNullOrEmpty('col');
}

You must call both commands:

where($field, '<>', null);
where($field, '<>', '');

because the MySql is handling empty strings and nulls different than a PHP

you also need to wrap those two commands with the closure to tell Eloquent to put generated code in parentheses and isolate MySql code:

(where col = null or where col = '')
fico7489
  • 7,931
  • 7
  • 55
  • 89
-4

Not sure, but this might work:

$user->albums()->where_in('col', array(NULL,''));
Sim0n222
  • 106
  • 4
  • 5
    NULL cannot be compared using `=` operator, so this won't work. Also, the method's name is `whereIn`, rather than `where_in`. Could've tested it, instead of writing "not sure, but this might work"… – jsphpl Jul 31 '17 at 13:37
  • 2
    @jsphpl Your comment is correct of course, but it should be noted that if you run `whereIn('col', [null, ''])` on a `Collection` object rather than a query builder, it _will_ work. Example: `$user->albums->whereIn('col', [null,'']);`. Note the use of the magic relational property `albums`, which returns a collection, and not `albums()`, which returns a query builder instance. – Soulriser Mar 23 '18 at 19:23