Mybatis之分组查询

28 篇文章 1 订阅
13 篇文章 0 订阅

在应用开发中,分组统计是非常经典的需求,在springboot+mybatis+mysql中实现分组统计。
学生信息统计场景,学生包含姓名、性别、年龄、地址等属性。

  • 按性别分组统计数量
  • 按地址分组统计数量
  • 按地址、性别分组统计数量

1、mysql中sql语句

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `sex` tinyint(2) NULL DEFAULT NULL,
  `age` tinyint(2) NULL DEFAULT NULL,
  `address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `nameKey`(`name`) USING BTREE COMMENT '唯一索引'
) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '曹操', 0, 20, '许昌');
INSERT INTO `student` VALUES (2, '刘备', 0, 20, '涿州');
INSERT INTO `student` VALUES (3, '孙权', 0, 20, '南京');
INSERT INTO `student` VALUES (4, '貂蝉', 1, 10, '许昌');
INSERT INTO `student` VALUES (5, '大乔', 1, 20, '扬州');
INSERT INTO `student` VALUES (6, '小乔', 1, 10, '扬州');
INSERT INTO `student` VALUES (7, '孙尚香', 1, 20, '南京');
INSERT INTO `student` VALUES (8, '关羽', 0, 10, '涿州');
INSERT INTO `student` VALUES (9, '张飞', 0, 10, '涿州');
INSERT INTO `student` VALUES (10, '曹仁', 0, 10, '许昌');

MySQL中,使用GROUP BY按某个字段,或者多个字段中的值,进行分组,字段中值相同的为一组。
SELECT 字段名1,字段名2,……
FROM 表名
WHERE BY 字段名1,字段名2,……[HAVING 条件表达式];
其中指定的字段名1、字段名2,是对查询结果分组的依据,HAVING关键字,指定条件表达式,对分组后的内容进行过滤,GROUP BY,一般和聚合函数一起使用。

SELECT sex,COUNT(id) FROM student GROUP BY sex

SELECT address,COUNT(id) FROM student GROUP BY address

SELECT address,sex,COUNT(id) FROM student GROUP BY address,sex

SELECT address,sex,COUNT(id) FROM student GROUP BY address,sex HAVING sex=1

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、mybatis
单个分组

	<select id="addressStudent" resultType="java.util.HashMap">
        SELECT address,COUNT(DISTINCT id) as 'count' FROM student GROUP BY address
    </select>
    
    List<HashMap<String,Long>> addressStudent();

两个分组

	<resultMap id="addressSex" type="java.util.HashMap">
        <result column="address" property="address" jdbcType="VARCHAR" />
        <result column="sex" property="sex" jdbcType="VARCHAR" />
        <result column="count" property="count" jdbcType="VARCHAR"/>
    </resultMap>
    
	<select id="addressSexStudent" resultMap="addressSex">
        SELECT address,sex,COUNT(DISTINCT id) as 'count' FROM student2 GROUP BY address,sex
    </select>
    
	List<HashMap<String,Long>> addressSexStudent();
    

结果

[
	{"address":"南京","sex":0,"count":1},
	{"address":"南京","sex":1,"count":1},
	{"address":"扬州","sex":1,"count":2},
	{"address":"涿州","sex":0,"count":3},
	{"address":"许昌","sex":0,"count":2},
	{"address":"许昌","sex":1,"count":1}
]
	<resultMap id="addressSex2" type="java.util.HashMap">
        <result column="address" property="address" jdbcType="VARCHAR" />
        <collection property="sexStudent" ofType="java.util.HashMap" javaType="java.util.ArrayList">
            <result column="sex" property="sex" jdbcType="VARCHAR" />
            <result column="count" property="count" jdbcType="VARCHAR"/>
        </collection>
    </resultMap>

	<select id="addressSexStudent2" resultMap="addressSex2">
        SELECT address,sex,COUNT(DISTINCT id) as 'count' FROM student2 GROUP BY address,sex
    </select>

	List<HashMap<Object,Object>> addressSexStudent2();

结果

[
	{
		"address":"南京",
		"sexStudent":[
			{"sex":0,"count":1},
			{"sex":1,"count":1}
		]
	},
	{
		"address":"扬州",
		"sexStudent":[
			{"sex":1,"count":2}
		]
	},
	{
		"address":"涿州",
		"sexStudent":[
			{"sex":0,"count":3}
		]
	},
	{
		"address":"许昌",
		"sexStudent":[
			{"sex":0,"count":2},
			{"sex":1,"count":1}
		]
	}
]

其中type是用java.util.Map类,这样才不会返回多余的字段null值,不要写表的实体类。collection集合里的ofType也是同理,要用java.util.Map类,javaType要用java.util.ArrayList类,这样才能返回一个List列表。

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值