如何在 Laravel 中为具有某种条件(例如是否有关系)的属性编写 orderBy 查询
how to write orderBy query for a attribute with some condition like has relation or not, in Laravel
我想编写一个查询以获取所有产品及其类型的列表。我喜欢按价格定单。
我的模型是这样的:
Product:
id
price
...
ProductType:
id
product_id
price
...
产品有价格属性,部分产品有类型(一对多关系)。每种类型的产品都有自己的价格。当产品有类型时,它的价格为0。这意味着产品类型的价格对我们很重要。
现在,当我想将 orderBy 写入价格时,我不知道如何编写同时包含价格的查询,我的意思是当产品有类型时,我们查询第一种价格,当我们没有类型时,我们必须查询产品自己价格。
我在 Laravel.
中完成了所有这些
Products::with('types')->orderBy(???)->paginate(15);
我需要的目标是,如果我们想按最便宜的价格排序,首先显示价格最低或其中一种类型的价格最低的产品,依此类推。即,可能会出现一种情况,一种有类型的产品被放在2种没有类型的产品之间。
使用 sortBy... 会有帮助。
Products::with('productType')->get()->sortByDesc('productType.price');
或使用
[评论后编辑]
$sortDirection = 'desc';
Products::with(['productType' => function ($query) use ($sortDirection) {
$query->orderBy('price', $sortDirection);
}])->get()->sortByDesc('price');
或型号
可以使用查询函数扩展关系:
public function productType()
{
return $this->hasMany('ProductType')->orderBy('price');
}
对我有用
[希望能奏效]
Product::with(['productType' => function ($query) use ($sortDirection) {
$query->orderBy('price', $sortDirection);
}])->get()->sortBy([
fn ($a, $b) => $a['product_type.price'] <=> $b['price'],
]);
Products::with('productType')
->orderBy('price')
->orderBy(
ProductType::select('price')
->whereColumn('products.id', '=' , 'product_types.product_id')
);
您可以用作一个范围,您可以将订单方向传递给它,这样您就可以使用 desc 和 asc,例如
Product.php
public function scopeOrderedByProductTypesPrice($query, $order="asc"){
$query
->orderBy('price')
->orderBy(
ProductType::select('price')
->whereColumn('products.id', '=' , 'product_types.product_id')
);
}
用例:
Products::with('productType')
->OrderedByProductTypesPrice('desc')
->get()
PS:如您所见,您还可以更新范围并接受列作为排序的参数
您可以使用leftJoin连接表并执行列求和,然后您可以对其进行排序。
Product::query()
->leftJoin('product_types', 'products.id', '=', 'product_types.product_id')
->select([
'products.id as product_id',
'products.name as product_name',
'products.price as product_price',
'product_types.id as product_type_id',
'product_types.name as product_type_name',
'product_types.price as product_type_price',
DB::raw('IFNULL((products.price), 0) + IFNULL((product_types.price), 0) as actual_product_prize'),
])
->orderBy('actual_product_prize')
->get();
您不能使用关系进行排序,因为每个产品可能有不同的产品类型和不同的奖品,您不能使用关系进行排序。
我想编写一个查询以获取所有产品及其类型的列表。我喜欢按价格定单。 我的模型是这样的:
Product:
id
price
...
ProductType:
id
product_id
price
...
产品有价格属性,部分产品有类型(一对多关系)。每种类型的产品都有自己的价格。当产品有类型时,它的价格为0。这意味着产品类型的价格对我们很重要。 现在,当我想将 orderBy 写入价格时,我不知道如何编写同时包含价格的查询,我的意思是当产品有类型时,我们查询第一种价格,当我们没有类型时,我们必须查询产品自己价格。 我在 Laravel.
中完成了所有这些Products::with('types')->orderBy(???)->paginate(15);
我需要的目标是,如果我们想按最便宜的价格排序,首先显示价格最低或其中一种类型的价格最低的产品,依此类推。即,可能会出现一种情况,一种有类型的产品被放在2种没有类型的产品之间。
使用 sortBy... 会有帮助。
Products::with('productType')->get()->sortByDesc('productType.price');
或使用
[评论后编辑]
$sortDirection = 'desc';
Products::with(['productType' => function ($query) use ($sortDirection) {
$query->orderBy('price', $sortDirection);
}])->get()->sortByDesc('price');
或型号
可以使用查询函数扩展关系:
public function productType()
{
return $this->hasMany('ProductType')->orderBy('price');
}
对我有用
[希望能奏效]
Product::with(['productType' => function ($query) use ($sortDirection) {
$query->orderBy('price', $sortDirection);
}])->get()->sortBy([
fn ($a, $b) => $a['product_type.price'] <=> $b['price'],
]);
Products::with('productType')
->orderBy('price')
->orderBy(
ProductType::select('price')
->whereColumn('products.id', '=' , 'product_types.product_id')
);
您可以用作一个范围,您可以将订单方向传递给它,这样您就可以使用 desc 和 asc,例如
Product.php
public function scopeOrderedByProductTypesPrice($query, $order="asc"){
$query
->orderBy('price')
->orderBy(
ProductType::select('price')
->whereColumn('products.id', '=' , 'product_types.product_id')
);
}
用例:
Products::with('productType')
->OrderedByProductTypesPrice('desc')
->get()
PS:如您所见,您还可以更新范围并接受列作为排序的参数
您可以使用leftJoin连接表并执行列求和,然后您可以对其进行排序。
Product::query()
->leftJoin('product_types', 'products.id', '=', 'product_types.product_id')
->select([
'products.id as product_id',
'products.name as product_name',
'products.price as product_price',
'product_types.id as product_type_id',
'product_types.name as product_type_name',
'product_types.price as product_type_price',
DB::raw('IFNULL((products.price), 0) + IFNULL((product_types.price), 0) as actual_product_prize'),
])
->orderBy('actual_product_prize')
->get();
您不能使用关系进行排序,因为每个产品可能有不同的产品类型和不同的奖品,您不能使用关系进行排序。