Hello,大家好,我是灰小猿,一个超会写bug的程序员!
今天这篇文章记录一个最近开发中遇到的mysql实战场景,觉得还挺典型的,就在此做一下记录。
先看一下举例场景:
mysql中学生表与学科表通过关联表建立关联,学生和学科为多对多的关系,现要求查询学生的数据,并根据学生表引用的多个学科中名称排列在前的学科的名称进行排序,
数据库表结构如下:
CREATE DATABASE school;USE school;CREATE TABLE student (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50),age INT
);CREATE TABLE course (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50),description VARCHAR(128)
);CREATE TABLE student_subject_rel (id INT AUTO_INCREMENT PRIMARY KEY,student_id INT,course_id INT
);
数据如下:
先来分析一下需求:首先是要求查询学生表中的数据,那么学生表就是作为主表,同时要求对查询结果进行排序,排序的要求是:以学生表中关联的多条学科数据中,学科名称排列在前的那个学科名称为依据对学生数据进行排序,
举个例子来说:
小王选了B课程和C课程
小李选了E课程和F课程
小张选了A课程和D课程
那么最终显示的结果就是:小张、小王、小李
对于这种情况,我们一般想到的是先根据学生表和关联表,找到每一个学生关联的所有学科,然后对每一个学生的学科进行排序,取到排列在第一位的学科,之后再根据第一次排序得到的学科名对学生进行排序,上面这种逻辑固然能够解决问题,但是使用不够简洁。
今天我们介绍一下另一种方法,采用GROUP_CONCAT
函数的方式来解决,只需要对学科完成一次排序即可。
首先我们来看一下GROUP_CONCAT
函数的含义:
GROUP_CONCAT函数
在 MySQL 中,GROUP_CONCAT
函数用于将查询结果按指定顺序连接成一个字符串。通常结合 GROUP BY
子句一起使用,可以将同一组的多个字段值连接成一个字符串。
以下是 GROUP_CONCAT
函数的基本语法:
SELECT GROUP_CONCAT(column_name ORDER BY order_column SEPARATOR ',')
FROM table_name
GROUP BY group_column;
-
column_name
:要连接的字段名。 -
order_column
:可选,用于指定连接时的排序顺序。 -
SEPARATOR ','
:可选,用于指定连接字符串之间的分隔符,默认为逗号(,)。 -
table_name
:表名。 -
group_column
:分组的字段名。
通过这样的语法,我们可以在查询中使用 GROUP_CONCAT
函数来将查询结果按照指定顺序连接成一个字符串。
下面使用GROUP_CONCAT
函数来解决上述场景问题:
首先以student表为主表,因为学生可能存在没有选课的情况,所以在关联表可能会存在没有关联数据的情况,但是这个时候学生数据也是应该要查询出来的,所以这个时候就需要使用左连接的方式进行连表查询,这样即使学生没有选课,仍然可以将学生的数据查询出来。
因为如果一个学生选择了多门课程的话,有可能会查出多条这个学生的数据,所以这个时候就需要使用GROUP BY根据学生的ID对数据进行分组,
同时使用GROUP_CONCAT
函数将每一个学生选的课程名称拼接成一个字符串作为一个外层排序的字段,并进行升序或降序排列。
最后的结果如下:
SELECT s.*, GROUP_CONCAT(c.name ORDER BY c.name) AS courses
FROM student s
LEFT JOIN student_course_rel r ON s.id = r.student_id
LEFT JOIN course c ON c.id = r.course_id
GROUP BY s.id
ORDER BY GROUP_CONCAT(c.name ORDER BY c.name) ASC;
执行结果:
如果想要在查询的过程中加入一些其他限定条件,比如搜索等,即可使用如下写法:
SELECT s.*, GROUP_CONCAT(c.name ORDER BY c.name) AS courses
FROM student s
LEFT JOIN student_course_rel r ON s.id = r.student_id
LEFT JOIN course c ON c.id = r.course_id
WHERE s.name LIKE '%四%'
GROUP BY s.id
ORDER BY GROUP_CONCAT(c.name ORDER BY c.name) ASC;
执行结果如下:
好了,以上就是GROUP_CONCAT
函数在实战中的一个使用场景总结记录。
我是灰小猿,我们下期见!