|MySQL使用基础,这么用就对了( 三 )


本文插图

其中 COUNT 函数需要额外注意 , 具体的内容可以参考这篇 。
如何进行分组
在统计结果时 , 往往需要对数据按照一定条件进行分组 , 对应就是 GROUP BY 语句 。
比如统计每个班级的学生人数:
SELECT class_id, COUNT(*) as student_count FROM student GROUP BY class_id;GROUP BY 后也可接多个列名 , 进行分组 , 比如按照班级和性别分组:
SELECT class_id, sex, COUNT(*) as student_count FROM student GROUP BY class_id, sex;HAVING 过滤和 WHERE 的区别
和 WHERE 一样 , 可以对分组后的数据进行筛选 。 区别在于 WHERE 适用于数据行 , HAVING 用于分组 。
而且 WHERE 支持的操作 , HAVING 也同样支持 。
比如可以筛选大于2人的班级:
SELECT class_id, COUNT(*) as student_count FROM student GROUP BY class_id HAVING student_count > 20;子查询
在一些更为复杂的情况中 , 往往会进行嵌套的查询 , 比如在获取结果后 , 该结果作为输入 , 去获取另外一组结果 。
在 SQL 中 , 查询可以分为关联子查询和非关联子查询 。
假设有如下的表结构:
-- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL DEFAULT '', `age` int(3) NOT NULL, `sex` varchar(10) NOT NULL DEFAULT '', `class_id` int(11) NOT NULL COMMENT '班级ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of Student -- ---------------------------- INSERT INTO `student` VALUES ('1', '胡一', 13, '男', '1'); INSERT INTO `student` VALUES ('3', '王阿', 11, '女', '1'); INSERT INTO `student` VALUES ('5', '王琦', 12, '男', '1'); INSERT INTO `student` VALUES ('7', '刘伟', 11, '女', '1'); INSERT INTO `student` VALUES ('7', '王意识', 11, '女', '2'); -- ---------------------------- DROP TABLE IF EXISTS `student_activities`; CREATE TABLE `student_activities` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL DEFAULT '', `stu_id` int(11) NOT NULL COMMENT '班级ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; INSERT INTO `student_activities` VALUES ('1', '博物馆', 1); INSERT INTO `student_activities` VALUES ('3, '春游', 3);非关联子查询
子查询从数据表中查询了数据结果 , 如果这个数据结果只执行一次 , 然后这个数据结果作为主查询的条件接着执行 。
这里想要查询和胡一相同班级的同学名称:
SELECT name FROM student WHERE class_id = (SELECT class_id FROM student WHERE name='胡一')这里先查到胡一的班级 , 只有一次查询 , 再根据该班级查找学生就是非关联子查询 。
【|MySQL使用基础,这么用就对了】关联子查询
如果子查询需要执行多次 , 即采用循环的方式 , 先从外部查询开始 , 每次都传入子查询进行查询 , 然后再将结果反馈给外部
再举个例子, 比如查询比每个班级中比平均年龄大的学生姓名信息:
SELECT name FROM student as s1 WHERE age > (SELECT AVG(age) FROM student as s2 where s1.class_id = s2.class_id)这里根据每名同学的班级信息 , 查找出对应班级的平均年龄 , 然后做判断 。 子查询每次执行时 , 都需要根据外部的查询然后进行计算 。 这样的子查询就是关联子查询 。
EXISTS 子查询
在关联子查询中 , 常会和 EXISTS 一起使用 。 用来判断条件是否满足 , 满足的话为 True , 不满足为 False 。


推荐阅读