首先说一下本示例中用到的数据结构(三张表):
-- ---------------------------- -- Table structure for test_department 部门表 -- ---------------------------- DROP TABLE IF EXISTS `test_department`; CREATE TABLE `test_department` ( `dep_id` int(11) NOT NULL, `dep_name` varchar(50) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of test_department -- ---------------------------- INSERT INTO `test_department` VALUES ('1', '部门1'); INSERT INTO `test_department` VALUES ('2', '部门2'); INSERT INTO `test_department` VALUES ('3', '部门3'); -- ---------------------------- -- Table structure for test_group 分组表 -- ---------------------------- DROP TABLE IF EXISTS `test_group`; CREATE TABLE `test_group` ( `gro_id` int(11) NOT NULL, `gro_name` varchar(50) NOT NULL, `gro_dep` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of test_group -- ---------------------------- INSERT INTO `test_group` VALUES ('1', '小组1', '1'); INSERT INTO `test_group` VALUES ('2', '小组2', '2'); INSERT INTO `test_group` VALUES ('3', '小组3', '3'); -- ---------------------------- -- Table structure for test_student 学生表 -- ---------------------------- DROP TABLE IF EXISTS `test_student`; CREATE TABLE `test_student` ( `stu_id` int(11) NOT NULL, `stu_name` varchar(50) NOT NULL, `stu_group` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of test_student -- ---------------------------- INSERT INTO `test_student` VALUES ('1', '张三', '1'); INSERT INTO `test_student` VALUES ('2', '李四', '2'); INSERT INTO `test_student` VALUES ('3', '王五', '3');
现在想要得到这样的数据:
查询每个部门中分组的数量 学生的数量,以部门分组进行查询
首先我们查询语句应该这样子写
select d.dep_id,d.dep_name,count(g.gro_id),count(s.stu_id) from test_department d left join test_group g on d.dep_id=g.gro_dep left join test_student s on s.stu_group=g.gro_id group by(d.dep_id)
然后得到的结果是:
看图中查询结果没有错,一共有三个部门,每个部门有一个分组,一个分组对应一个学生。
其实这个查询语句中有隐藏的错误,当我们把数据这样子修改一下时:
INSERT INTO `test_student` VALUES ('1', '张三', '1'); INSERT INTO `test_student` VALUES ('2', '李四', '1'); INSERT INTO `test_student` VALUES ('3', '王五', '1');
这个时候我们理想中得到的结果应该是
一共是三个部门,每个部门有一个分组,其中一分组有学生三个,其他学生分组为0
可是我们得到的结果却是:
明明一个部门有三个分组,怎么一部门直接有三个三组了呢。
其实问题的原因在于,这个时候查询语句是三表联查,count在统计行数时,把left join test_student的行数也统计了进去
这个时候我们就应该使用DISTINCT关键字来进行查询了,
select d.dep_id,d.dep_name,count(DISTINCT g.gro_id),count(DISTINCT s.stu_id) from test_department d left join test_group g on d.dep_id=g.gro_dep left join test_student s on s.stu_group=g.gro_id group by(d.dep_id)
这个时候得到到的数据就和我们想象中的一样了,
DISTINCT的用法其一就是过滤掉多余的重复记录只保留一条
其他具体用法等碰到的时候在做解释。