Laravel Eloquent 模型按局部列和关系模型列值排序
Posted
技术标签:
【中文标题】Laravel Eloquent 模型按局部列和关系模型列值排序【英文标题】:Laravel Eloquent model order by local column and relation models column value 【发布时间】:2020-01-08 11:05:21 【问题描述】:我有 2 个模型:
-
产品,具有
sort
字段。
Stock,具有 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
这是 Product -> Stock的关系
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】:您可以使用合并方法。但我认为您的数据库设计不正确。我认为最好将数量字段放在产品表上。 如果您出于任何原因想要保留此设计,最好在stocks 表中为product_id 设置唯一索引。例如,您的一个产品(id=1)现在有两个数量。这在现实世界中是不可能的
$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;
您可以按照以下示例进行查询:
$products = DB::table('products')
->join('stocks', 'stocks.product_id', '=', 'products.id')
->selectRaw(' product_id, sum(quantity) as tot')
->groupBy('product_id')
->orderByRaw(
"CASE WHEN quantity = 0 THEN 1 ELSE 0 END ASC"
)
->get();
return $products;
【讨论】:
感谢您的帮助。我已经像你的第二个例子那样做了。问题是在库存表中,我将不同的存储与产品连接起来。这就像 manyToMany 关系。 很高兴您找到了答案。以上是关于Laravel Eloquent 模型按局部列和关系模型列值排序的主要内容,如果未能解决你的问题,请参考以下文章