基本语法
SELECT FROM WHERE GROUP BY HAVING ORDER BY LIMIT
先过滤行,然后分组,筛选组,对剩余组排序,选取指定的组集合。
记住:一旦分组完成,我们的后续操作都是对分组得到的虚拟表进行操作。
GROUP BY子句中列出来的每个列必须是检索列或有效的表达式(但不能是聚集函数)
举例说明
下面来看一个例子:刚刚开了一把王者荣耀battle,这把一共有六个英雄上阵,如下所示:
+--------+------+--------+---------+
| name | sex | job | gold |
+--------+------+--------+---------+
| 嫦娥 | 女 | 法师 | 5600.00 |
| 杨戬 | 男 | 战士 | 5600.00 |
| 梦琪 | 男 | 战士 | 8500.00 |
| 火女 | 女 | NULL | 5600.00 |
| 苏烈 | 男 | 坦克 | 8600.00 |
| 阿珂 | 女 | 刺客 | 5600.00 |
+--------+------+--------+---------+
1.战斗进行了一会,现在来算一算哪个职业的经济最多?
select job,sum(gold) from battle group by job;
+-------- +-------------+
| job | sum(gold) |
+--------+--------------+
| NULL | 5600.00 |
| 刺客 | 5600.00 |
| 坦克 | 8600.00 |
| 战士 | 14100.00 |
| 法师 | 5600.00 |
+--------+-----------+
可以看出来,战士获得的经济最多。因为火女的职业不知道,所以被单独分到一个组,
知识点来了:如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多个NULL,它们将作为一个分组返回。
2.如果我只想查看美女英雄的职业分组经济情况咋办?
select job,sum(gold) from battle where sex='女' group by job;
+--------+-----------+
| job | sum(gold) |
+---------+-----------+
| NULL | 5600.00 |
| 刺客 | 5600.00 |
| 法师 | 5600.00 |
+--------+-----------+
3.如果我只想查看美女英雄的法师组的经济?
select job,sum(gold) from battle where sex='女' group by job having job='法师';
+--------+-----------+
| job | sum(gold) |
+--------+-----------+
| 法师 | 5600.00 |
+--------+-----------+
4.如果想查看每个组内有哪些人怎么办,GROUP_CONCAT()函数就发挥作用了。
select GROUP_CONCAT(name),job,sum(gold) from battle group by job;
+--------------------+--------+-----------+
| GROUP_CONCAT(name) | job | sum(gold) |
+------------------+---------+------------+
| 火女 | NULL | 5600.00 |
| 阿珂 | 刺客 | 5600.00 |
| 苏烈 | 坦克 | 8600.00 |
| 杨戬,梦琪 | 战士 | 14100.00 |
| 嫦娥 | 法师 | 5600.00 |
+--------------------+--------+-----------+
知识点:GROUP_CONCAT()会把组内的所有成员列出来。
5.如果想在分组统计数据基础上再进行相同的统计,可以使用 with rollup
select GROUP_CONCAT(name),job,sum(gold) from battle group by job with rollup;
+-------------------------------------------+--------+-----------+
| GROUP_CONCAT(name) | job | sum(gold) |
+--------------------------------------------+--------+--------------+
| 火女 | NULL | 5600.00 |
| 阿珂 | 刺客 | 5600.00 |
| 苏烈 | 坦克 | 8600.00 |
| 杨戬,梦琪 | 战士 | 14100.00 |
| 嫦娥 | 法师 | 5600.00 |
| 火女,阿珂,苏烈,杨戬,梦琪,嫦娥 | NULL | 39500.00 |
+-------------------------------------------+-----------+-------------+
6.COUNT(*)会统计我们表中的NULL值,如果不想统计NULL值,请写COUNT(字段名)
select GROUP_CONCAT(name),job,sum(gold),count(*) as '人数' from battle group by job;
+--------------------+--------+-----------+--------+
| GROUP_CONCAT(name) | job | sum(gold) | 人数 |
+------------------+--------+-------------+--------+
| 火女 | NULL | 5600.00 | 1 |
| 阿珂 | 刺客 | 5600.00 | 1 |
| 苏烈 | 坦克 | 8600.00 | 1 |
| 杨戬,梦琪 | 战士 | 14100.00| 2 |
| 嫦娥 | 法师 | 5600.00 | 1 |
+--------------------+--------+-----------+--------+
select GROUP_CONCAT(name),job,sum(gold),count(job) as '人数' from battle group by job;
+--------------------+--------+-----------+--------+
| GROUP_CONCAT(name) | job | sum(gold) | 人数 |
+------------------+--------+-------------+-------+
| 火女 | NULL | 5600.00 | 0 |
| 阿珂 | 刺客 | 5600.00 | 1 |
| 苏烈 | 坦克 | 8600.00 | 1 |
| 杨戬,梦琪 | 战士 | 14100.00| 2 |
| 嫦娥 | 法师 | 5600.00 | 1 |
+--------------------+--------+-----------+--------+