我正在使用 Laravel 和 MySQL 构建一个错误跟踪系统,到目前为止我有 3 个表
fillers as f
:保存填充符 id、名字和姓氏列:- id,= el.tech,
- 名字,
- 姓氏
error_type as et
:保存一个表来描述可能的错误类型并分配一个 id 列:- ID,
- 名称 = el.error_id
error_logs as el
:保存所有填充列的所有错误:- ID,
- error_id, =et.name
- 技术,=f.id
public function countAllLogs()
{
$errorLog = DB::table('fillers AS f')
->select(
'f.id as id',
'f.first_name as first_name',
'f.last_name as last_name',
// 'f.location as location',
'et.name as error_type',
)
->selectRaw(
'count(el.error_id) as count',
)
->groupBy('f.id')
->groupBy('el.error_id')
->leftjoin('error_logs as el', 'f.id', '=', 'el.tech')
->leftjoin('error_types as et', 'et.id', '=', 'el.error_id')
->get();
return response($errorLog, 200);
}
使用Postman Get函数给出以下示例
{
"id": 59,
"first_name": "Steve",
"last_name": "Martian",
"error_type": "ndc",
"count": 3
},
{
"id": 59,
"first_name": "Steve",
"last_name": "Martian",
"error_type": "jumper",
"count": 1
}
这几乎就是我想要的,但它根据“error_type”分开。我见过“pivot”,但不确定如何用我所拥有的来实现它。
期望的输出是
{
"id": 59,
"first_name": "Steve",
"last_name": "Martian",
"jumper": 1,
"ndc": 3
}
谢谢。
最佳答案
您可以使用 flatMap
集合方法来实现此目的。我假设会出现多个 id,因此也会使用 groupBy
和 map
。
$errorLog = DB::table('fillers AS f')->...->get();
$json = $errorLog
->groupBy('id')
->map->flatMap(fn($item) => [
'id' => $item->id,
'first_name' => $item->first_name,
'last_name' => $item->last_name,
$item->error_type => $item->count
])
->values()
->toJson();
return response($json, 200);
说明
这是原始集合。我添加了几个条目来演示不同的 id。
array:4 [
0 => {#4540
+"id": 59
+"first_name": "Steve"
+"last_name": "Martian"
+"error_type": "ndc"
+"count": 3
}
1 => {#4567
+"id": 59
+"first_name": "Steve"
+"last_name": "Martian"
+"error_type": "jumper"
+"count": 1
}
2 => {#4569
+"id": 57
+"first_name": "qwer"
+"last_name": "Martian"
+"error_type": "ndc"
+"count": 3
}
3 => {#4573
+"id": 58
+"first_name": "asdf"
+"last_name": "Martian"
+"error_type": "jumper"
+"count": 1
}
]
groupBy('id')
:按 id 对集合进行分组。这对于下一步很重要。
array:3 [
59 => Illuminate\Support\Collection {#4592
#items: array:2 [
0 => {#4540
+"id": 59
+"first_name": "Steve"
+"last_name": "Martian"
+"error_type": "ndc"
+"count": 3
}
1 => {#4567
+"id": 59
+"first_name": "Steve"
+"last_name": "Martian"
+"error_type": "jumper"
+"count": 1
}
]
}
57 => Illuminate\Support\Collection {#4557
#items: array:1 [
0 => {#4569
+"id": 57
+"first_name": "qwer"
+"last_name": "Martian"
+"error_type": "ndc"
+"count": 3
}
]
}
58 => Illuminate\Support\Collection {#4591
#items: array:1 [
0 => {#4573
+"id": 58
+"first_name": "asdf"
+"last_name": "Martian"
+"error_type": "jumper"
+"count": 1
}
]
}
]
flatMap(Closure)
:映射集合,然后折叠它。与map(Closure)->collapse()
相同。
map->flatMap(fn($item) => [...])
:简写
map(function ($grouped) {
return $grouped->flatMap(function ($item) {
return [...];
});
});
由于高阶收集方法,这种表示法才成为可能。
如果 groupBy
步骤未完成,那么您最终会得到一个项目,数据完全混合在一起。
这是 map->flatMap(Closure)
之后 Collection 的样子:
array:3 [
59 => Illuminate\Support\Collection {#4590
#items: array:5 [
"id" => 59
"first_name" => "Steve"
"last_name" => "Martian"
"ndc" => 3
"jumper" => 1
]
}
57 => Illuminate\Support\Collection {#4570
#items: array:4 [
"id" => 57
"first_name" => "qwer"
"last_name" => "Martian"
"ndc" => 3
]
}
58 => Illuminate\Support\Collection {#4588
#items: array:4 [
"id" => 58
"first_name" => "asdf"
"last_name" => "Martian"
"jumper" => 1
]
}
]
values()
:丢弃数组键。这很重要,因为如果 toJson()
尝试保存键,它会生成一个 json 对象而不是 json 数组。
您可以通过一个简单的实验亲自看到这一点:比较之间的结果
json_encode([ ['a' => 2, 'b' => 3] ]);
json_encode([1 => ['a' => 2, 'b' => 3] ]);
array:3 [
0 => Illuminate\Support\Collection {#4590
#items: array:5 [
"id" => 59
"first_name" => "Steve"
"last_name" => "Martian"
"ndc" => 3
"jumper" => 1
]
}
1 => Illuminate\Support\Collection {#4570
#items: array:4 [
"id" => 57
"first_name" => "qwer"
"last_name" => "Martian"
"ndc" => 3
]
}
2 => Illuminate\Support\Collection {#4588
#items: array:4 [
"id" => 58
"first_name" => "asdf"
"last_name" => "Martian"
"jumper" => 1
]
}
]
toJson()
:将集合转换为 json 字符串:(我添加了换行符以提高可读性)
[
{
"id":59,
"first_name":"Steve",
"last_name":"Martian",
"ndc":3,
"jumper":1
},
{
"id":57,
"first_name":"qwer",
"last_name":"Martian",
"ndc":3
},
{
"id":58,
"first_name":"asdf",
"last_name":"Martian",
"jumper":1
}
]
关于mysql - 如何连接多个表并使用一个表中的数据来创建输出列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70586676/