Laravel范围与联盟

时间:2017-06-27 09:29:01

标签: php sql laravel eloquent

我需要一种方法来按两列对模型进行排序(但不是按x,y的顺序排序)。我有一个priority列,可以提升'结果中的模型,以及未设置created_at时应该排序的标准priority。我发现这样做的唯一方法就是工会。

使用这样的查询:

(SELECT * FROM `charts` WHERE priority IS NOT NULL ORDER BY priority ASC) 
UNION (SELECT * FROM `charts` WHERE priority IS NULL AND created_at IS NOT NULL ORDER BY CREATED_AT ASC) 
UNION (SELECT * FROM `charts` WHERE created_at IS NULL)

所以我尝试做类似的事情:

public function scopeSortPriority($query)
{
    return $query->whereNotNull('priority')
        ->orderBy('priority')
        ->union($query->whereNull('priority')
            ->whereNotNull('created_at')
            ->orderBy('created_at'))
        ->union($query->whereNull('priority')
            ->whereNull('created_at'));
}

但遗憾的是它不起作用。

还有其他方法可以在SQL中实现我想要的吗?否则 - 我应该如何重建此范围以使其有效?

1 个答案:

答案 0 :(得分:1)

问题是您在工会中使用$query

如果您知道查询的常见部分和您的工会总是\DB::table('charts'),您可以这样做:

$query->whereNotNull('priority')
    ->orderBy('priority')
    ->union(\DB::table('charts')->whereNull('priority')
        ->whereNotNull('created_at')
        ->orderBy('created_at'))
    ->union(\DB::table('charts')->whereNull('priority')
        ->whereNull('created_at'));

如果$query相同但可以更改,则可以执行以下操作:

    $query2 = clone $query;
    $query3 = clone $query;

    $query->whereNotNull('priority')
    ->orderBy('priority')
    ->union($query2->whereNull('priority')
        ->whereNotNull('created_at')
        ->orderBy('created_at'))
    ->union($query3->whereNull('priority')
        ->whereNull('created_at'));

在这两种情况下,sql的输出都是:

(select * from `charts` where `priority` is not null order by `priority` asc) union (select * from `charts` where `priority` is null and `created_at` is not null order by `created_at` asc) union (select * from `charts` where `priority` is null and `created_at` is null)