在 laravel 中查询此类数据的最佳做法是什么?
What is the best practice to query this type of data in laravel?
我有 3 个表结构,如下所示:-
products
id
name
1
apple
2
orange
branches
id
name
1
Branch 1
2
Branch 2
stocks
id
branch_id
product_id
qty
1
1
1
10
2
1
2
20
3
2
1
30
4
2
2
40
预期结果:-
No.
Name
Branch 1
Branch 2
Total
1
apple
10
30
40
2
orange
20
40
60
下面是我的代码,它正在运行并且可以获得预期的结果,但我不喜欢我的方式,尤其是 $stock[0]->product->name 部分,我认为必须有另一个合适的最好不要循环 blade 中的分支,是否可以在查询中完成所有操作?
StockController
$branches = Branch::get();
$stocks = Stock::get()->groupBy('product_id');
//$stocks->toArray() output
array:2 [
1 => array:2 [
0 => array:4 [
"id" => 1
"product_id" => 1
"branch_id" => 1
"qty" => 10
]
1 => array:4 [
"id" => 1
"product_id" => 1
"branch_id" => 2
"qty" => 30
]
]
2 => array:2 [
0 => array:4 [
"id" => 1
"product_id" => 2
"branch_id" => 1
"qty" => 20
]
1 => array:4 [
"id" => 1
"product_id" => 2
"branch_id" => 2
"qty" => 40
]
]
]
stock_index.blade.php
@foreach ($stocks as $stock)
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $stock[0]->product->name }}</td>
@foreach ($branches as $branch)
<td>{{ $stock->firstWhere('branch_id', $branch->id)->qty ?? 0 }}</td>
@endforeach
<td>{{ $stock->sum('qty') }}</td>
</tr>
@endforeach
希望对您有所帮助
$branches = Branch::pluck('name', 'id');
$query_string = "";
foreach ($branches as $key => $value) {
$query_string .= "sum(CASE WHEN stocks.branch_id = '". $key ."' THEN stocks.qty END) as " . str_replace(' ', '_', $value) . "_sum , ";
}
$query_string .= 'sum(stocks.qty) as total';
$stocks = Stock::join('products', 'stocks.product_id', '=', 'products.id')->select(
'products.name as product_name',
DB::raw($query_string)
)->groupBy('product_id')->orderBy('product_id','asc')->get();
我建议您使用此代码:
$query = "";
foreach (Branch::query()->pluck('name', 'id') as $key => $value) {
$query .= "sum(CASE WHEN stocks.branch_id = '". $key ."' THEN stocks.qty END) as " . str_replace(' ', '_', $value) . "_sum , ";
}
$query .= 'sum(stocks.qty) as total';
$stocks = Stock::query()->join('products', 'stocks.product_id', '=', 'products.id')
->select(
'products.name as product_name',
DB::raw($query)
)->groupBy('product_id')
->orderBy('product_id','asc')
->get();
我有 3 个表结构,如下所示:-
products
id | name |
---|---|
1 | apple |
2 | orange |
branches
id | name |
---|---|
1 | Branch 1 |
2 | Branch 2 |
stocks
id | branch_id | product_id | qty |
---|---|---|---|
1 | 1 | 1 | 10 |
2 | 1 | 2 | 20 |
3 | 2 | 1 | 30 |
4 | 2 | 2 | 40 |
预期结果:-
No. | Name | Branch 1 | Branch 2 | Total |
---|---|---|---|---|
1 | apple | 10 | 30 | 40 |
2 | orange | 20 | 40 | 60 |
下面是我的代码,它正在运行并且可以获得预期的结果,但我不喜欢我的方式,尤其是 $stock[0]->product->name 部分,我认为必须有另一个合适的最好不要循环 blade 中的分支,是否可以在查询中完成所有操作?
StockController
$branches = Branch::get();
$stocks = Stock::get()->groupBy('product_id');
//$stocks->toArray() output
array:2 [
1 => array:2 [
0 => array:4 [
"id" => 1
"product_id" => 1
"branch_id" => 1
"qty" => 10
]
1 => array:4 [
"id" => 1
"product_id" => 1
"branch_id" => 2
"qty" => 30
]
]
2 => array:2 [
0 => array:4 [
"id" => 1
"product_id" => 2
"branch_id" => 1
"qty" => 20
]
1 => array:4 [
"id" => 1
"product_id" => 2
"branch_id" => 2
"qty" => 40
]
]
]
stock_index.blade.php
@foreach ($stocks as $stock)
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $stock[0]->product->name }}</td>
@foreach ($branches as $branch)
<td>{{ $stock->firstWhere('branch_id', $branch->id)->qty ?? 0 }}</td>
@endforeach
<td>{{ $stock->sum('qty') }}</td>
</tr>
@endforeach
希望对您有所帮助
$branches = Branch::pluck('name', 'id');
$query_string = "";
foreach ($branches as $key => $value) {
$query_string .= "sum(CASE WHEN stocks.branch_id = '". $key ."' THEN stocks.qty END) as " . str_replace(' ', '_', $value) . "_sum , ";
}
$query_string .= 'sum(stocks.qty) as total';
$stocks = Stock::join('products', 'stocks.product_id', '=', 'products.id')->select(
'products.name as product_name',
DB::raw($query_string)
)->groupBy('product_id')->orderBy('product_id','asc')->get();
我建议您使用此代码:
$query = "";
foreach (Branch::query()->pluck('name', 'id') as $key => $value) {
$query .= "sum(CASE WHEN stocks.branch_id = '". $key ."' THEN stocks.qty END) as " . str_replace(' ', '_', $value) . "_sum , ";
}
$query .= 'sum(stocks.qty) as total';
$stocks = Stock::query()->join('products', 'stocks.product_id', '=', 'products.id')
->select(
'products.name as product_name',
DB::raw($query)
)->groupBy('product_id')
->orderBy('product_id','asc')
->get();