MySql对统计多个维度

数据准备

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `STU_ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `STU_NAME` varchar(6) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '学生姓名',
  `STU_AGE` int(11) NULL DEFAULT NULL COMMENT '学生年龄',
  `STU_ADDRESS` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '学生地址',
  PRIMARY KEY (`STU_ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '李华', 23, '江西');
INSERT INTO `student` VALUES (2, '张三', 23, '广东');
INSERT INTO `student` VALUES (3, '李四', 24, '浙江');
INSERT INTO `student` VALUES (4, '王五', 22, '浙江');
INSERT INTO `student` VALUES (5, '赵六', 24, '福建');
INSERT INTO `student` VALUES (6, '张三', 24, '浙江');

SET FOREIGN_KEY_CHECKS = 1;

提出问题


平时开发中经常会遇到求总数的情况,mysql的count()函数能很好的解决我们的需求,例如查询姓名叫张三的总人数
select count() from student where stu_name = '张三'

现在改变上述需求,查询出姓名叫张三的总人数、地址为浙江的总人数、年龄为23的总人数。
对于该需求也很好实现,我们分别写出三条SQL即可实现
select count(*) from student where stu_name = '张三'
select count(*) from student where stu_address = '浙江'
select count(*) from student where stu_age = 23
然后将三条语句的结果在业务层合并就可得到最终结果。

但是如果只用一条SQL我们该如何实现上述需求?

一.使用IF函数

SELECT
count(if(stu_name = '张三', 1, null)),
count(if(STU_ADDRESS = '浙江',1, null)),
count(if(STU_AGE = 23, 1, null))
FROM 
student

一.使用case...when...

SELECT
count(case STU_NAME WHEN '张三' THEN STU_NAME ELSE null  END) AS TOTAL_ONE,
count(case STU_ADDRESS WHEN '浙江' THEN STU_ADDRESS ELSE null  END) AS TOTAL_TWO,
count(case STU_AGE WHEN 23 THEN STU_AGE ELSE null  END) AS TOTAL_THREE
FROM 
student

上述两种写法仅限在表数据不大的情况下使用,如果表的数据量非常大还是选择分开统计,因为上述的写法相当于全表扫描,然后对每行记录再做判断,效率比较低。