如何在Laravel中使用Eloquent对NULL值进行排序

时间:2013-07-14 21:42:25

标签: php many-to-many laravel eloquent

我的员工和团队表之间有很多关系。我已经创建了数据透视表,并且所有工作都正常。但是,我在employees表上有一个sortOrder列,用于确定它们显示的顺序。 sortOrder列中值为1的员工应该是第一个,值2应该是第二个,依此类推。 (如果按降序排序,则向后)sortOrder列是一个允许空值的整数列。

我已经设置了我的组模型来按排序列对员工进行排序,但我遇到了一个问题。始终首先显示空值。我尝试使用ISNULL和类似的SQL方法代替常用的“asc”或“desc”,但我只收到错误。

以下是我的群组模型中的代码:

class Group extends Eloquent {

public function employees()
    {
        return $this->belongsToMany("Employee")->orderBy('sortOrder', 'asc');
    }
}

这是我在控制器中用来访问我的模型的内容:

$board = Group::find(6)->employees;

Laravel最后排序NULL值的技巧是什么?

8 个答案:

答案 0 :(得分:31)

Laravel没有考虑ISNULL方法,但是,您可以将其作为原始查询传递并仍然使用它,因为它比IF语句更有效,结果将保持不变如果你超过1000000名员工(接受的答案),就像这样:

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

<强>更新 您还可以使用orderByRaw()方法:

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

答案 1 :(得分:23)

只需在字段中添加减号并将订单更改为DESC。

$q->orderBy(\DB::raw('-`sortOrder`'), 'desc');

答案 2 :(得分:7)

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

<强>解释
IF声明解决了这个问题。如果找到NULL值,则会将一些大数字分配给sortOrder。如果发现不是NULL值,则使用实际值。

答案 3 :(得分:6)

在Laravel 5.2或更高版本中,只需致电orderByRaw。您甚至可以对聚合值而不是列进行排序。在以下示例中,如果没有子模型,max_st可以是null

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');

答案 4 :(得分:3)

您也可以这样做,而不是依赖任意大数字:

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

它还有一个受SQLite支持的好处。

答案 5 :(得分:2)

我最近使用Laravel 5.6遇到了这个问题,其中junkystu的答案非常适合我。但是我们的测试框架使用sqlite,因此测试不断返回500错误。

这是我们想出的,应该与数据库驱动程序无关。

升序

$query->orderBy(DB::raw('column_to_sort IS NULL, column_to_sort'), 'asc');

下降

$query->orderBy(DB::raw('column_to_sort IS NOT NULL, column_to_sort'), 'desc');

答案 6 :(得分:0)

PostgreSQL的解决方法

对于数字类型:

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

对于文字类型:

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

诀窍是将排序列中的NULL值替换为零(或空字符串),以便可以将其排序为普通的整数(或文本)值。

答案 7 :(得分:-1)

->orderBy('sortOrder', 'is', 'null')->orderBy('sortOrder', 'asc')

似乎工作。