1.需求:
想要统计出camille1,camille2,camille3,camille4每个人都有几件衣服,没有衣服的就为0件。
数据表(clothes)
id | name | color |
---|---|---|
1 | camille1 | blue |
2 | camille2 | blue |
3 | camille2 | red |
4 | camille4 | yellow |
5 | camille4 | blue |
数据表(user)
id | name |
---|---|
1 | camille1 |
2 | camille2 |
3 | camille3 |
4 | camille4 |
2.实现
- a.一般情况我们会这样写SQL语句:
SELECT `name`, count(*) AS clothes_count FROM `clothes` WHERE `name` IN (‘camille1’, ‘camille2’, ‘camille3’,‘camille4’) GROUP BY `name`
但是结果为
从输出结果看少了这条数据
name | clothes_count |
---|---|
camille3 | 0 |
- b.实际SQL应当这样写:
以原来查询出来的结果作为一个子表然后leftjoin这个子表查出我们想要的结果
SELECT DISTINCT a. name, IFNULL(b.clothes_count, 0) AS clothes_count FROM `user` AS a LEFT JOIN(
SELECT `name`, count(*) AS clothes_count FROM `clothes` WHERE`name` IN (‘camille1’, ‘camille2’, ‘camille3’,‘camille4’) GROUP BY `name`
) AS b ON `a`.`name` = `b`.`name` WHERE `a`.`name` IN (‘camille1’, ‘camille2’, ‘camille3’,‘camille4’)
3.用Laravel框架来实现上述SQL语句
//查询出计数为零的字段
public function index(){
$name = ['camille1','camille2','camille3','camille4'];
$clothesQuery = new Clothes();
$clothesCountObj = $clothesQuery->selectRaw('count(*) as clothes_count, name')
->whereIn('name', $name)
->groupBy('name');
//为了返回结果有计数为零的字段
$clothes = DB::table('user as a')
->select(DB::raw('IFNULL( b.clothes_count, 0 ) AS clothes_count,a.name'))
->distinct()
->whereIn('a.name', $name)
->leftJoin(\DB::raw("({$clothesCountObj->toSql()}) as b"), function ($join) use ($clothesCountObj) {
$join->mergeBindings($clothesCountObj->getQuery())->on('a.name', '=', 'b.name');
})
->get();
return $clothes;
}