我有2个型号:
sort
字段的产品。我想按排序字段(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');
}
答案 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;