Mysql案例之GROUP_CONCAT函數(shù)的具體使用
今天這篇文章記錄一個最近開發(fā)中遇到的mysql實戰(zhàn)場景,覺得還挺典型的,就在此做一下記錄。
先看一下舉例場景:
mysql中學(xué)生表與學(xué)科表通過關(guān)聯(lián)表建立關(guān)聯(lián),學(xué)生和學(xué)科為多對多的關(guān)系,現(xiàn)要求查詢學(xué)生的數(shù)據(jù),并根據(jù)學(xué)生表引用的多個學(xué)科中名稱排列在前的學(xué)科的名稱進行排序,
數(shù)據(jù)庫表結(jié)構(gòu)如下:
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 );
數(shù)據(jù)如下:



先來分析一下需求:首先是要求查詢學(xué)生表中的數(shù)據(jù),那么學(xué)生表就是作為主表,同時要求對查詢結(jié)果進行排序,排序的要求是:以學(xué)生表中關(guān)聯(lián)的多條學(xué)科數(shù)據(jù)中,學(xué)科名稱排列在前的那個學(xué)科名稱為依據(jù)對學(xué)生數(shù)據(jù)進行排序,
舉個例子來說:
小王選了B課程和C課程
小李選了E課程和F課程
小張選了A課程和D課程
那么最終顯示的結(jié)果就是:小張、小王、小李
對于這種情況,我們一般想到的是先根據(jù)學(xué)生表和關(guān)聯(lián)表,找到每一個學(xué)生關(guān)聯(lián)的所有學(xué)科,然后對每一個學(xué)生的學(xué)科進行排序,取到排列在第一位的學(xué)科,之后再根據(jù)第一次排序得到的學(xué)科名對學(xué)生進行排序,上面這種邏輯固然能夠解決問題,但是使用不夠簡潔。
今天我們介紹一下另一種方法,采用GROUP_CONCAT 函數(shù)的方式來解決,只需要對學(xué)科完成一次排序即可。
首先我們來看一下GROUP_CONCAT 函數(shù)的含義:
GROUP_CONCAT函數(shù)
在 MySQL 中,GROUP_CONCAT 函數(shù)用于將查詢結(jié)果按指定順序連接成一個字符串。通常結(jié)合 GROUP BY 子句一起使用,可以將同一組的多個字段值連接成一個字符串。
以下是 GROUP_CONCAT 函數(shù)的基本語法:
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 函數(shù)來將查詢結(jié)果按照指定順序連接成一個字符串。
下面使用GROUP_CONCAT 函數(shù)來解決上述場景問題:
首先以student表為主表,因為學(xué)生可能存在沒有選課的情況,所以在關(guān)聯(lián)表可能會存在沒有關(guān)聯(lián)數(shù)據(jù)的情況,但是這個時候?qū)W生數(shù)據(jù)也是應(yīng)該要查詢出來的,所以這個時候就需要使用左連接的方式進行連表查詢,這樣即使學(xué)生沒有選課,仍然可以將學(xué)生的數(shù)據(jù)查詢出來。
因為如果一個學(xué)生選擇了多門課程的話,有可能會查出多條這個學(xué)生的數(shù)據(jù),所以這個時候就需要使用GROUP BY根據(jù)學(xué)生的ID對數(shù)據(jù)進行分組,
同時使用GROUP_CONCAT 函數(shù)將每一個學(xué)生選的課程名稱拼接成一個字符串作為一個外層排序的字段,并進行升序或降序排列。
最后的結(jié)果如下:
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;
執(zhí)行結(jié)果:

如果想要在查詢的過程中加入一些其他限定條件,比如搜索等,即可使用如下寫法:
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;
執(zhí)行結(jié)果如下:

好了,以上就是GROUP_CONCAT 函數(shù)在實戰(zhàn)中的一個使用場景總結(jié)記錄。
到此這篇關(guān)于Mysql案例之GROUP_CONCAT函數(shù)的具體使用的文章就介紹到這了,更多相關(guān)Mysql GROUP_CONCAT函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
my.cnf(my.ini)重要參數(shù)優(yōu)化配置說明
本文針對mysql不同存儲引擎,MyISAM與Innodb進行了講解如何進行my.cnf(my.ini)的參數(shù)優(yōu)化2018-03-03
使用mysql的disctinct group by查詢不重復(fù)記錄
非常不錯的方法,用mysql的group by解決不重復(fù)記錄的問題,看來我需要學(xué)習(xí)的地方太多了2008-08-08
driver-class-name:?com.mysql.jdbc.Driver爆紅的問題解決
在springboot項目工程中想要進行數(shù)據(jù)庫配置,driver-class-name:?com.mysql.cj.jdbc.Driver始終報錯,本文就來介紹一下如何解決,感興趣的可以了解一下2024-07-07
Django+mysql配置與簡單操作數(shù)據(jù)庫實例代碼
這篇文章主要介紹了Django+mysql配置與簡單操作數(shù)據(jù)庫實例,需要的朋友可以參考下2017-07-07

