Mysql案例之GROUP_CONCAT函数详解

news2024/10/24 2:29:53

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 函数在实战中的一个使用场景总结记录。

我是灰小猿,我们下期见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1498086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux设备模型(九) - bus/device/device_driver/class

一,设备驱动模型 1,概述 在前面写的驱动中,我们发现编写驱动有个固定的模式只有往里面套代码就可以了,它们之间的大致流程可以总结如下: 实现入口函数xxx_init()和卸载函数xxx_exit() 申请设备号 register_chrdev_r…

首发:鸿蒙面试真题分享【独此一份】

最早在23年华为秋季发布会中,就已经宣布了“纯血鸿蒙”。而目前鸿蒙处于星河版中,加速了各大互联网厂商的合作。目前已经有200参与鸿蒙的原生应用开发当中。对此各大招聘网站上的鸿蒙开发需求,每日都在增长中。 2024大厂面试真题 目前的鸿蒙…

OpenHarmony教程指南—ArkUI中组件、通用、动画、全局方法的集合

介绍 本示例为ArkUI中组件、通用、动画、全局方法的集合。 本示例使用 Tabs容器组件搭建整体应用框架,每个 TabContent内容视图 使用 div容器组件 嵌套布局,在每个 div 中使用 循环渲染 加载此分类下分类导航数据,底部导航菜单使用 TabCont…

LeetCode 2917.找出数组中的 K-or 值:基础位运算

【LetMeFly】2917.找出数组中的 K-or 值:基础位运算 力扣题目链接:https://leetcode.cn/problems/find-the-k-or-of-an-array/ 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 nums 中的 K-or 是一个满足以下条件的非负整数: 只有…

如何合理布局子图--确定MATLAB的subplot子图位置参数

确定MATLAB的subplot子图位置参数 目录 确定MATLAB的subplot子图位置参数摘要1. 问题描述2. 计算过程2.1 确定子图的大小和间距2.2 计算合适的figure大小2.3 计算每个子图的position数据 3. MATLAB代码实现3.1 MATLAB代码3.2 绘图结果 4. 总结 摘要 在MATLAB中,使用…

网络编程套接字(1)—网络编程基础

目录 一、为什么需要网络编程? 二、什么是网络编程 三、网络编程中的基本概念 1、发送端和接收端 2、请求和响应 3、客户端和服务端 四、常见的客户端服务端模型 1、一问一答模型 2、一问多答模型 3、多问一答模型 4、多问多答模型 一、为什么需要网络编程? 为什么…

(二十二)从零开始搭建k8s集群——高可用kubernates集群搭建上篇

前言 本节内容分为上、中、下三篇,上篇主要是关于搭建k8s的基础环境,包括服务器基本环境的配置(网络、端口、主机名、防火墙、交换分区、文件句柄数等)、docker环境部署安装配置、镜像源配置等。中篇会介绍k8s的核心组件安装、k8…

rk3568 恢复出厂设置横屏

author daisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 daisy.skye_嵌入式,Linux,Qt-CSDN博客daisy.skye擅长嵌入式,Linux,Qt,等方面的知识https://blog.csdn.net/qq_40715266?typeblog 在使用rk3568开发过程,虽然显示的方向已经改成了横屏,但是恢…

4.1k star,官方出品的redis桌面管理工具——redislnsight

导航 令人抓狂的大key加载RedisInsight 简介RedisInsight的亮点GitHub 地址安装和使用RedisInsight 下载安装 使用RedisInsight redis数据库可视化直观的CLI(Command-Line Interface)日志分析和命令分析 结语参考 令人抓狂的大key加载 工欲善其事必先利…

JavaScript基础4之原型的原型继承、原型链和理解对象的数据属性、访问器属性

JavaScript基础 原型原型继承问题解决 原型链isPrototypeOf()Object.getPrototypeOf() 理解对象数据属性访问器属性 原型 原型继承 继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript中大多是借助原型对象实现继承的特性。…

sudo command not found

文章目录 一句话Intro其他操作 一句话 sudo 某命令 改成 sudo -i 某命令 试试。 -i 会把当前用户的环境变量带过去,这样在sudo的时候,有更高的权限,有本用户的环境变量(下的程序命令)。 -i, --login run login shell as the target user; a …

软件测试相关概念和bug的相关总结

文章目录 什么是测试什么是需求测试用例(CASE)什么是BUG软件的生命周期开发模型瀑布模型螺旋模型增量模型和迭代模型 敏捷测试模型v模型W模型(双V模型) 软件测试的生命周期如何描述一个bugbug的级别bug的生命周期.产生争执怎么办 什么是测试 测试是测试人员用来检验软件的实际运…

全自动玻璃切割机控制系统设计

目 录 摘 要 I Abstract II 引 言 1 1 玻璃切割机控制系统设计 4 1.1系统方案选择 4 1.2玻璃切割机的工作原理 4 1.3工艺过程 5 1.4玻璃切割机的控制要求 6 2硬件设计 8 2.1控制部分设计 8 2.2驱动部分设计 8 2.2.1步进电机及驱动器的选型 8 2.2.2步进电机驱动器接口电路设计 …

VM 虚拟机 ubuntu 解决无法连接网络问题

添加网卡法 就是在虚拟机的设置那里多增加一个网卡

每日OJ题_链表②_力扣24. 两两交换链表中的节点

目录 力扣24. 两两交换链表中的节点 解析代码 力扣24. 两两交换链表中的节点 24. 两两交换链表中的节点 难度 中等 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即&…

顺序表以及单链表

目录 1顺序表&#xff08;规范&#xff09; 2单链表&#xff08;规范&#xff09; 3总结 1顺序表&#xff08;规范&#xff09; #include<iostream> using namespace std; #define MAXSIZE 100 #define ok -1 #define error -2 typedef int Status; typedef int…

支小蜜校园防欺凌系统如何有效应对学生霸凌?

学生霸凌不仅直接伤害到被霸凌者的身心健康&#xff0c;也对整个校园的和谐氛围构成了威胁。为了应对这一问题&#xff0c;校园防欺凌系统应运而生&#xff0c;成为维护校园安全、保护学生权益的重要工具。那么当校园防欺凌系统面对学生霸凌时&#xff0c;该如何有效应对呢&…

K8S之实现业务的蓝绿部署

如何实现蓝绿部署 什么是蓝绿部署&#xff1f;蓝绿部署的优势和缺点优点缺点 通过k8s实现线上业务的蓝绿部署 什么是蓝绿部署&#xff1f; 部署两套系统&#xff1a;一套是正在提供服务系统&#xff0c;标记为 “绿色” &#xff1b;另一套是准备发布的系统&#xff0c;标记为…

JS函数

目录 1.Function声明 2.匿名函数 3.函数表达式 4.箭头函数 5.构造函数 个人版JS函数使用&#xff1a; 函数的声明&#xff1a;函数如果有return则返回的是 return 后面的值&#xff0c;如果函数没有有return 声明方式一&#xff1a; 声明方式二&#xff1a;变量名声明…

0x04_数组_指针_字符串

数组 数组的定义与使用 数组是具有一定顺序关系的若干相同类型变量的集合体&#xff0c;组成数组的变量称为该数组的元素。 给出下面程序的输出&#xff1a; #include <iostream> using namespace std; int main() {int a[10], b[10];for(int i 0; i < 10; i) {a[…