我正在一个项目中,我需要以Excel格式导出产品销售报告。我正在使用Maatwebsite/Laravel-Excel
我有三个模型。
product.php
class products extends Model
{
protected $table='products';
public $timestamps = false;
protected $fillable = ['image', 'asin','price','strategy_id'];
public function orderDetails()
{
return $this->hasMany(order_details::class, 'SKU', 'asin');
}
}
orders.php
class orders extends Model
{
protected $table = 'orders';
public $timestamps = false;
protected $fillable = ['id','date','quantity','totalAmount'];
public function orderDetails()
{
return $this->hasMany(order_details::class);
}
}
order_details.php
class order_details extends Model
{
protected $table = 'order_details';
protected $fillable = ['id','order_id','SKU','unitPrice','quantity','totalPrice'];
public function order()
{
return $this->belongsTo(orders::class);
}
现在,我想计算每种产品在过去30天,60天和90天的溶胶时间。
要注意的点
我当前的查询是:-
$products = products::query();
// Some where clauses/filters
$products = $products->get();
foreach($products as $product)
{
// Getting the order_details which has this product
$orderIds = order_details::where('SKU','=',$product->asin)->pluck('order_id');
$product->sales30days = orders::whereIn('id', $orderIds)->whereBetween('date', [Carbon::now()->subDays(30), Carbon::now()])->sum('quantity');
$product->sales60days = orders::whereIn('id', $orderIds)->whereBetween('date', [Carbon::now()->subDays(60), Carbon::now()])->sum('quantity');
$product->sales90days = orders::whereIn('id', $orderIds)->whereBetween('date', [Carbon::now()->subDays(90), Carbon::now()])->sum('quantity');
$product->sales120days = orders::whereIn('id', $orderIds)->whereBetween('date', [Carbon::now()->subDays(120), Carbon::now()])->sum('quantity');
$product->totalSold = orders::whereIn('id', $orderIds)->sum('quantity');
}
上面的查询为我提供了所需的结果,但是要花费很多时间,并且对性能不友好。我有超过10万种产品。
$products->paginate(100)
之类的分页吗?答案 0 :(得分:2)
问题在于您要进行很多查询,这不可避免地会很慢。该解决方案应该具有更好的性能,因为您只需进行两次查询。
$orders = orders::with(['orderDetails'])->get();
$now = Carbon::now();
$quantities = [];
foreach($orders as $order) {
$daysOld = $order->date->diffInDays($now);
foreach ($order->orderDetails as $details) {
if (!isset($quantities[$details->SKU])) {
$quantities[$details->SKU]['30'] = 0;
$quantities[$details->SKU]['60'] = 0;
$quantities[$details->SKU]['90'] = 0;
$quantities[$details->SKU]['120'] = 0;
$quantities[$details->SKU]['total'] = 0;
}
if ($daysOld <= 30) {
$quantities[$details->SKU]['30'] += $details->quantity;
}
if ($daysOld <= 60) {
$quantities[$details->SKU]['60'] += $details->quantity;
}
if ($daysOld <= 90) {
$quantities[$details->SKU]['90'] += $details->quantity;
}
if ($daysOld <= 120) {
$quantities[$details->SKU]['120'] += $details->quantity;
}
$quantities[$details->SKU]['total'] += $details->quantity;
}
}
return products::all()->map(function ($product) use ($quantities) {
$product->sales30days = $quantities[$product->asin]['30'];
$product->sales60days = $quantities[$product->asin]['60'];
$product->sales90days = $quantities[$product->asin]['90'];
$product->sales120days = $quantities[$product->asin]['120'];
$product->salesTotal = $quantities[$product->asin]['total'];
return $product;
});