How to sort NULL values last using Eloquent in Laravel

前端 未结 8 1230
终归单人心
终归单人心 2020-12-08 14:29

I\'ve got a many to many relationship between my employees and groups table. I\'ve created the pivot table, and all is working correctly with that. However, I\'ve got a sort

相关标签:
8条回答
  • 2020-12-08 14:55

    Laravel does not take into consideration the ISNULL method however, you can pass it in as a raw query and still make use of it as it's more efficient than IF statements and the results will stay the same if you ever go beyond 1000000 employees (accepted answer), like so:

    public function employees()
    {
        return $this->hasMany('Employee')
                    ->orderBy(DB::raw('ISNULL(sortOrder), sortOrder'), 'ASC');
    }
    

    Update: You can also use the orderByRaw() method:

    public function employees()
    {
        return $this->hasMany('Employee')
                    ->orderByRaw('ISNULL(sortOrder), sortOrder ASC');
    }
    
    0 讨论(0)
  • 2020-12-08 14:59

    In Laravel 5.2 or higher just call orderByRaw. You even able to sort through aggregated value rather than a column. In the following example max_st can be null if there is no submodels.

    Model::where('act', '2')
        ->leftJoin('submodels', 'model.id', '=', 'submodels.model_id')
        ->select('models.*', DB::raw('MAX(submodels.st) as max_st')),
        ->orderByRaw('max_st DESC NULLS LAST');
    
    0 讨论(0)
  • 2020-12-08 14:59

    Instead of relying on an arbitrary large number you can also do:

    public function employees()
    {
        return $this
            ->hasMany('Employee')
            ->select(['*', DB::raw('sortOrder IS NULL AS sortOrderNull')])
            ->orderBy('sortOrderNull')
            ->orderBy('sortOrder');
    }
    

    It has an added benefit of being supported by SQLite.

    0 讨论(0)
  • 2020-12-08 15:04

    A workaround for PostgreSQL

    For numeric types:

    DB::table('t')
        ->select(['id', 'val'])
        ->orderBy(DB::raw("coalesce(val, 0)"), 'desc')
    

    For text types:

    orderBy(DB::raw("coalesce(val, '')"), 'desc')
    

    The trick is to replace NULL values in the sorting column to zero (or empty string) so that it could be sorted as an ordinary integer (or text) value.

    0 讨论(0)
  • 2020-12-08 15:09
    public function employees()
    {
        return $this
            ->hasMany('Employee')
            ->select(['*', DB::raw('IF(`sortOrder` IS NOT NULL, `sortOrder`, 1000000) `sortOrder`')])
            ->orderBy('sortOrder', 'asc');
    }
    

    Explanation:
    The IF statement solves the issue here. If NULL value is found, some big number is assigned to sortOrder instead. If found not NULL value, real value is used.

    0 讨论(0)
  • 2020-12-08 15:12
    ->orderBy('sortOrder', 'is', 'null')->orderBy('sortOrder', 'asc')
    

    Seems to work.

    0 讨论(0)
提交回复
热议问题