withCount的使用
基礎(chǔ)概念
統(tǒng)計關(guān)聯(lián)數(shù)量,只能使用與Eloquent模型,不用使用DB::table這種查詢,使用時候要存在明確的關(guān)聯(lián)Model
沒有withSum、withAvg這樣的用法,可以通過withCount實現(xiàn)多種聚合查詢,適用于一對多的查詢
數(shù)據(jù)表
班級表(student_class)
- id
- name
學(xué)生表(student)
- id
- name
- age
- student_id
代碼分析
// Model:StudentClass
public function Student(){
return $this->hasMany(Student::class) ;
}
//1.查詢所有班級以及每個班級的人數(shù)數(shù)量,默認(rèn)形式count(id)
$result1=StudentClass::withCount('student')->get();
// 執(zhí)行結(jié)果:
$result2=[
0 => [
"id" => 1
"name" => "一年級"
"student_count" => 2
]
1 => [
"id" => 2
"name" => "二年級"
"student_count" => 1
]
];
//2.查詢所有班級以及每個班級的所有人數(shù)以及平均年齡
$result = StudentClass::withCount([
'student as avg_age' => function ($query) {
$query->select(DB::raw('avg(age)'));
},
'student as sum_id' => function ($query) {
$query->select(DB::raw('sum(id)'));
},
])
//進(jìn)行having篩選,直接使用as字段名稱
->having('sum_id','>',6)
//進(jìn)行排序,直接使用as的字段名稱
->orderBy('avg_age','Asc')
->get()
// 執(zhí)行結(jié)果:
$result2=[
0 => [
"id" => 1
"name" => "一年級"
"avg_age" => "15.0000"
"sum_id" => "3"
]
1 => [
"id" => 2
"name" => "二年級"
"avg_age" => "10.0000"
"sum_id" => "3"
]
];
執(zhí)行sql
-- $result1
select
`student_class`.*,
(
select
count(*)
from
`student`
where
`student_class`.`id` = `student`.`class_id`
) as `student_count`
from
`student_class`
-- result2
select
`student_class`.*,
(
select
avg(age)
from
`student`
where
`student_class`.`id` = `student`.`class_id`
) as `avg_age`,
(
select
sum(id)
from
`student`
where
`student_class`.`id` = `student`.`class_id`
) as `sum_id`
from
`student_class`
后話
- 使用withCount進(jìn)行查詢
sum、avg的時候,在function中的使用selectRaw無效的,應(yīng)該使用DB::raw這種形式 - 一定要是用
as+name,這里的name決定的顯示結(jié)果中的字段名稱 - 可以再上進(jìn)行統(tǒng)計查詢之后使用
having進(jìn)行再次篩選,還可以使用orderBy進(jìn)行排序操作 - 如果指定
select個別字段,一定要將select放在withCount的前面,放在后面的話會顯示不出withCount的字段信息 - 如果想用原生的方法實現(xiàn)withCount的效果的,采用以下代碼
$result = StudentClass::select('id',DB::raw('(select count(id) from student where student.class_id=student_class.id) as sum_count'))