Laravel雄辩的模型按本地列和关系模型列值排序

时间:2019-09-05 14:05:13

标签: mysql sql laravel eloquent

我有2个型号:

  1. 具有sort字段的产品。
  2. 库存,其中包含product_id和数量字段。

我想按排序字段(ASC)订购产品,但库存数量等于0的产品必须位于列表的末尾。

例如

产品

id     sort
1      3
2      4
3      2
4      1

库存

product_id    quantity
1             2
1             3
2             5
3             0
4             2

预期列表(产品ID)-4,1,2,3

我已经写了我需要做的SQL查询。

select p.url, p.sort, s.tot
from products p
inner join (select product_id, sum(quantity) as tot from stocks group by product_id) s on p.id = s.product_id
order by case when s.tot = 0 then 1 else 0 end, p.sort asc

这是产品->库存的关系

public function stocks() {
    return $this->hasMany('\App\Stock', 'product_id');
}

是否有一种方法可以使用Eloquent Model的作用域获取此类清单?

更新

解决方案。

public function scopeOrdered($query, $notInStock = false)
    {
        if($notInStock)
            return $query->join(DB::raw("(
                select product_id, sum(quantity) as tot
                from stocks
                group by product_id
                ) s"), 'products.id', '=', 's.product_id')->orderByRaw("case when s.tot = 0 then 1 else 0 end, products.sort ASC");
        else
            return $query->orderBy('sort', 'asc');
    }

1 个答案:

答案 0 :(得分:1)

您可以使用合并方法。但是我认为您的数据库设计不正确。我认为最好将数量字段放在产品表上。 如果您出于某种原因希望保留此设计,请在stocks表中为product_id设置唯一索引。例如,您的一种产品(id = 1)现在有两种数量。在现实世界中这是不可能的

<%-array%>

您可以按照以下示例进行查询:

    $query1 = Product::whereHas('stocks' , function ($q) {
        $q->where('quantity', '<>',  0);
    })->with('stocks')->orderBy('sort','asc')->get();

    $query2 = Product::whereHas('stocks' , function ($q) {
        $q->where('quantity', 0);
    })->with('stocks')->get();


    $merged = $query1->merge($query2);

    return $merged;