用MySQL的GROUP_CONCAT函数轻松解决多表联查的聚合问题
大家好呀,我是summo,最近遇到了一个功能需求,虽然也是CURD,但属于那种比较复杂一点的CURD,话不多说,我们先看一下需求。
需求如下:
有三张表,学生表、课程表、学生课程关联表,关联关系如下图:
要求实现的功能:
- 支持输入名称模糊查询,可以是学生名称也可以是课程名称,但只有一个输入框;
- 要求以学生为主信息,一个学生所选的多门课程聚合展示;
- 支持分页查询。
产品原型大致如下:
原型画的有点丑,不过应该可以看的懂,需求还是合理的,现在压力给到了后端,如何写SQL才能查出这样的数据结构来呢?
首先,我们把表建一下,初始化一些模拟数据。
学生表:t_student
-- 创建表
CREATE TABLE `t_student` (
`id` bigint NOT NULL COMMENT '物理主键',
`stu_name` varchar(255) DEFAULT NULL COMMENT '学生名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- 添加数据
INSERT INTO `t_student` VALUES (1, '张三');
INSERT INTO `t_student` VALUES (2, '李四');
INSERT INTO `t_student` VALUES (3, '王五');
课程表:t_course
-- 创建表
CREATE TABLE `t_course` (
`id` bigint NOT NULL COMMENT '物理主键',
`course_name` varchar(255) DEFAULT NULL COMMENT '课程名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- 添加数据
INSERT INTO `t_course` VALUES (1, '语文');
INSERT INTO `t_course` VALUES (2, '数学');
INSERT INTO `t_course` VALUES (3, '英语');
学生课程关联表:t_student_course_rel
-- 创建表
CREATE TABLE `t_student_course_rel` (
`id` bigint NOT NULL COMMENT '物理主键',
`stu_id` bigint DEFAULT NULL COMMENT '学生ID',
`course_id` bigint DEFAULT NULL COMMENT '课程ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- 添加数据
INSERT INTO `t_student_course_rel` VALUES (1, 1, 1);
INSERT INTO `t_student_course_rel` VALUES (2, 1, 2);
INSERT INTO `t_student_course_rel` VALUES (3, 2, 1);
INSERT INTO `t_student_course_rel` VALUES (4, 2, 2);
INSERT INTO `t_student_course_rel` VALUES (5, 2, 3);
INSERT INTO `t_student_course_rel` VALUES (6, 3, 2);
INSERT INTO `t_student_course_rel` VALUES (7, 3, 3);
这里我先不讲原理,直接放答案,大家可以先去试一下看看效果,然后再回来看原理。
聚合查询SQL如下:
SELECT
t1.id, -- 学生ID
t1.stu_name, -- 学生姓名
GROUP_CONCAT(t3.id) AS course_ids, -- 合并该学生所选课程的ID
GROUP_CONCAT(t3.course_name) AS course_names -- 合并该学生所选课程的名称
FROM
t_student t1 -- 主表:学生信息
LEFT JOIN t_student_course_rel t2 ON t1.id = t2.stu_id -- 连接学生和课程关系表(左连接)
LEFT JOIN t_course t3 ON t2.course_id = t3.id -- 连接课程表(左连接)
WHERE
t1.stu_name LIKE CONCAT('%', '张', '%') -- 筛选学生姓名中包含'张'的记录
OR t3.course_name LIKE CONCAT('%', '张', '%') -- 或者筛选课程名称中包含'张'的记录
GROUP BY
t1.id, -- 按学生ID分组
t1.stu_name -- 按学生姓名分组
LIMIT 0,20 -- 分页查询
返回结果
从结果可以看到,course_ids和course_names将张三选择的课程聚合起来了,其中的主要功臣就是GROUP_CONCAT
,它是 MySQL 中的一个聚合函数,主要用于将多个行的值连接成一个字符串。这在需要将某个列的多个值合并为一个结果时特别有用。比如,查询一个表中的某些记录,并将某个字段的多行值合并在一起,以便于更直观地查看。
- 聚合功能:与其他聚合函数(如 SUM、COUNT 等)类似,GROUP_CONCAT 将多个行的结果合并为一个单一的字符串。
- 分隔符:默认情况下,多个值之间用逗号 , 作为分隔符,但可以使用 SEPARATOR 关键字指定其他分隔符。
- 使用场景:通常用于 GROUP BY 查询中,以便将分组后的字段进行合并。
这篇文章虽然简短,但却是我日常开发的心得笔记。正所谓“千里之行,始于足下;细流汇聚,成就江海”,写作的乐趣正是在于不断积累。随着时间的推移,你会发现这些点滴已成为一笔珍贵的财富。
至此,全文结束,再会!
用MySQL的GROUP_CONCAT函数轻松解决多表联查的聚合问题的更多相关文章
- mysql之group_concat函数
mysql之group_concat函数 在介绍GROUP_CONCAT之前,我们先来看看concat()函数和concat_ws()函数. 先准备一个测试数据库: mysql> select ...
- MySQL中group_concat函数 --- 很有用的一个用来查询出所有group by 分组后所有 同组内的 内容
本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) . MySQL中group_concat函数 完整的语法如下: grou ...
- MySQL中group_concat函数-和group by配合使用
MySQL中group_concat函数 完整的语法如下: group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔 ...
- MySQL中group_concat函数深入理解
本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) . 一.MySQL中group_concat函数 完整的语法如下: gr ...
- MySQL中group_concat函数
本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) .MySQL中group_concat函数完整的语法如下:group_c ...
- 【转】mysql的group_concat函数,默认最大长度是1024
mysql的group_concat函数,默认最大长度是1024 查询sql: show variables like 'group_concat_max_len'; 设置方式: 修改配置文件my.i ...
- mysql中group_concat函数用法
该函数返回带有来自一个组的连接的非NULL值的字符串结果.该函数是一个增强的Sybase SQL Anywhere支持的基本LIST()函数. 语法结构: GROUP_CONCAT([DISTINCT ...
- 利用MySQL 的GROUP_CONCAT函数实现聚合乘法
MySQL 聚合函数里面提供了加,平均数.最小,最大等,可是没有提供乘法,我们这里来利用MYSQL现有的GROUP_CONCAT函数实现聚合乘法. 先创建一张演示样例表: CREATE TABLE ` ...
- MYSQL中group_concat( )函数中参数的排序方法
使用mysql中的group_concat( )函数连接指定字段时,可以先对该字段进行排序. PS:是因为二刷mysql的51道题的第12题遇到的:查询和" 01 "号同学学习的课 ...
- 关于Mysql中GROUP_CONCAT函数返回值长度的坑
1.GROUP_CONCAT函数: 功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果. 语法:group_concat( [distinct] 要连接的字段 [order b ...
随机推荐
- 请查收“国产化率认证报告”(100%)——RK3568J工业核心板
创龙科技RK3568J核心板获得"100%国产化"认证日前,创龙科技"国产化率100%认证"的核心板再添一员!RK3568J工业核心板(SOM-TL3568)获 ...
- welcome to chifan-duck's blog
博主简介 截至至 2024 博主事一名初二学生. 为什么开博客园 因为博主是一名 Oier. 博客内容 OI 知识(科技)的普及 & 题解 为什么叫 chifan-duck ? 原本博主再各大 ...
- Java项目静态资源映射的几种方式
一.Springboot 1.webjars方式 我们之前使用Maven构建一个Web项目时,在main目录下会存在一个webapp的目录,我们以前都是将所有的页面或静态资源导在这个目录下,但现在使用 ...
- SpringMVC面试题及答案
SpringMvc 的控制器是不是单例模式,如果是,有什么问题,怎么解决? 问题:单例模式,在多线程访问时有线程安全问题 解决方法:不要用同步,在控制器里面不能写字段 SpringMvc 中控制器的注 ...
- Linux 提权-NFS 共享
本文通过 Google 翻译 NFS Share no_root_squash – Linux Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校 ...
- [rCore学习笔记 04]安装SSH
因为每一个老嵌入式都喜欢使用他的老windows进行开发,因此我决定使用SSH来开发rust,这样也不用在虚拟机里边再装一个vscode. 参考博客 如何在windows下使用vscode连接linu ...
- Python 正则表达式实战之Java日志解析
需求描述 基于生产监控告警需求,需要对Java日志进行解析,提取相关信息,作为告警通知消息的内容部分. 提取思路 具体怎么提取,提取哪些内容呢?这里笔者分析了大量不同形态的生产日志,最后总结出4种形态 ...
- UE5打包后,无法切换关卡的问题
首先是普通的会遇到的问题,比如多个Level不在同一目录,或者不在默认的Maps目录打包不成功这时候要设置,Project Settings-> Packaging 上面保证没问题之后,打包发现 ...
- vue8小时带刻度的时间轴,根据当前时间实时定位
效果图: 需求: 1 开始时间.结束时间可配置2 时差固定8小时3 根据当前时间初始化位置4 每隔5s刷新位置5 超过结束时间停止刷新 HTML: <div class="time-a ...
- 人脸识别项目打包成exe的过程遇到的问题
我最近重新拾起了计算机视觉,借助Python的opencv还有face_recognition库写了个简单的图像识别demo,额外定制了一些内容,原本想打包成exe然后发给朋友,不过在这当中遇到了许多 ...