作者:極客小俊 一個(gè)專注于web技術(shù)的80后
我不用拼過聰明人煎饼,我只需要拼過那些懶人 我就一定會(huì)超越大部分人!
@極客小俊,簡書官方首發(fā)原創(chuàng)文章
企業(yè)博客:
?? GeekerJun ??
B站干貨 :
?? Bilibili.com ??
前言
GROUP_CONCAT()函數(shù)在MySQL到底起什么作用呢 校赤?
有些小伙伴還覺得它很神秘其實(shí)不然吆玖,今天就來講講這個(gè)函數(shù)的實(shí)際操作以及相關(guān)案例、
我將從concat()函數(shù) --- concat_ws()函數(shù)----到最后的group_concat()函數(shù)逐一講解! 讓小伙伴摸清楚其使用方法 !
首先我們來建立一個(gè)測(cè)試的表和數(shù)據(jù)马篮,代碼如下
CREATE TABLE `per` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pname` varchar(50) DEFAULT NULL,
`page` int(11) DEFAULT NULL,
`psex` varchar(50) DEFAULT NULL,
`paddr` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4;
INSERT INTO `per` VALUES ('1', '王小華', '30', '男', '北京');
INSERT INTO `per` VALUES ('2', '張文軍', '24', '男', '上海');
INSERT INTO `per` VALUES ('3', '羅敏', '19', '女', '重慶');
INSERT INTO `per` VALUES ('4', '張建新', '32', '男', '重慶');
INSERT INTO `per` VALUES ('5', '劉婷', '26', '女', '成都');
INSERT INTO `per` VALUES ('6', '劉小亞', '22', '女', '重慶');
INSERT INTO `per` VALUES ('7', '王建軍', '22', '男', '貴州');
INSERT INTO `per` VALUES ('8', '謝濤', '28', '男', '海南');
INSERT INTO `per` VALUES ('9', '張良', '26', '男', '上海');
INSERT INTO `per` VALUES ('10', '黎記', '17', '男', '貴陽');
INSERT INTO `per` VALUES ('11', '趙小麗', '26', '女', '上海');
INSERT INTO `per` VALUES ('12', '張三', null, '女', '北京');
concat()函數(shù)
首先我們先學(xué)一個(gè)函數(shù)叫concat()函數(shù), 這個(gè)函數(shù)非常簡單
功能:就是將多個(gè)字符串連接成一個(gè)字符串
語法:concat(字符串1, 字符串2,...) 字符串參數(shù)用逗號(hào)隔開!
返回值: 結(jié)果為連接參數(shù)產(chǎn)生的字符串沾乘,如果有任何一個(gè)參數(shù)為null,則返回值為null浑测。
案例1
select concat('重慶','北京','上海');
效果如下圖: 是不是覺得很簡單 很直觀呢!
案例2
這有一張表
+----+-----------+------+------+--------+
| id | pname | page | psex | paddr |
+----+-----------+------+------+--------+
| 1 | 王小華 | 30 | 男 | 北京 |
| 2 | 張文軍 | 24 | 男 | 上海 |
| 3 | 羅敏 | 19 | 女 | 重慶 |
| 4 | 張建新 | 32 | 男 | 重慶 |
| 5 | 劉婷 | 26 | 女 | 成都 |
| 6 | 劉小亞 | 22 | 女 | 重慶 |
| 7 | 王建軍 | 22 | 男 | 貴州 |
| 8 | 謝濤 | 28 | 男 | 海南 |
| 9 | 張良 | 26 | 男 | 上海 |
| 10 | 黎記 | 17 | 男 | 貴陽 |
| 11 | 趙小麗 | 26 | 女 | 上海 |
| 12 | 張三 | NULL | 女 | 北京 |
+----+-----------+------+------+--------+
#-- 執(zhí)行如下語句
select concat(pname,page,psex) from per;
#--結(jié)果
+-------------------------+
| concat(pname,page,psex) |
+-------------------------+
| 王小華30男 |
| 張文軍24男 |
| 羅敏19女 |
| 張建新32男 |
| 劉婷26女 |
| 劉小亞22女 |
| 王建軍22男 |
| 謝濤28男 |
| 張良26男 |
| 黎記17男 |
| 趙小麗26女 |
| NULL |
+-------------------------+
#--為什么會(huì)有一條是NULL呢?
#--那是因?yàn)榈?2條數(shù)據(jù)中的page字段為空翅阵,根據(jù)有一個(gè)字段為空結(jié)果就為NULL的理論推導(dǎo)出 查詢出的最后一條記錄為NULL!
但是大家一定會(huì)發(fā)現(xiàn)雖然連在一起顯示了 但是彼此沒有分隔符啊 看起來好難受 對(duì)不對(duì)? 所以接下來我們就來講講衍生出來的 concat_ws()函數(shù)
concat_ws()函數(shù)
功能:concat_ws()函數(shù) 和 concat()函數(shù)一樣,也是將多個(gè)字符串連接成一個(gè)字符串掷匠,但是可以指定分隔符!
語法:concat_ws(separator, str1, str2, ...) 第一個(gè)參數(shù)指定分隔符, 后面依舊是字符串
separator就是分隔符字符!
需要注意的是分隔符不能為null滥崩,如果為null,則返回結(jié)果為null槐雾。
案例代碼:
select concat_ws(',',pname,page,psex) from per;
#--以逗號(hào)分割 結(jié)果如下
+--------------------------------+
| concat_ws(',',pname,page,psex) |
+--------------------------------+
| 王小華,30,男 |
| 張文軍,24,男 |
| 羅敏,19,女 |
| 張建新,32,男 |
| 劉婷,26,女 |
| 劉小亞,22,女 |
| 王建軍,22,男 |
| 謝濤,28,男 |
| 張良,26,男 |
| 黎記,17,男 |
| 趙小麗,26,女 |
| 張三,女 |
+--------------------------------+
#--把分隔符指定為null夭委,結(jié)果全部變成了null
select concat_ws(null,pname,page,psex) from per; #--錯(cuò)誤的
+---------------------------------+
| concat_ws(null,pname,page,psex) |
+---------------------------------+
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
+---------------------------------+
group_concat()函數(shù)
接下來就要進(jìn)入我們本文的主題了,group_concat()函數(shù), 理解了上面兩個(gè)函數(shù)的作用和用法 就對(duì)理解group_concat()函數(shù)有很大幫助了!
功能:將group by產(chǎn)生的同一個(gè)分組中的值連接起來募强,返回一個(gè)字符串結(jié)果株灸。
語法:group_concat( [distinct] 要連接的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] )
注意: 中括號(hào)是可選的
分析: 通過使用distinct可以排除重復(fù)值;如果希望對(duì)結(jié)果中的值進(jìn)行排序擎值,可以使用order by子句慌烧;separator是一個(gè)字符串值,缺省為一個(gè)逗號(hào)鸠儿。
以下我準(zhǔn)備了幾個(gè)案例 小伙伴們可以選擇性的去閱讀 并且把代碼復(fù)制到MySQL中執(zhí)行以下就可以知道用法了!
重點(diǎn)注意
- group_concat只有與group by語句同時(shí)使用才能產(chǎn)生效果 所以使用 GROUP_CONCAT()函數(shù)必須對(duì)源數(shù)據(jù)進(jìn)行分組屹蚊,否則所有數(shù)據(jù)會(huì)被合并成一行
- 需要將拼接的結(jié)果去重的話,可與DISTINCT結(jié)合使用即可
案例1
需求: 比如我們要查在重慶的有哪些人? 并且把這些人的名字用 '-' 字符分隔開 然后顯示出來, SQL語句如下
#--這里就用到了 : 取出重復(fù)进每、顯示排序汹粤、 定義分隔字符
select
paddr,
group_concat(distinct pname order by pname desc separator '-') as '人'
from per
group by paddr;
#--結(jié)果為:
+--------+----------------------------+
| paddr | 人 |
+--------+----------------------------+
| 上海 | 趙小麗-張良-張文軍 |
| 北京 | 王小華-張三 |
| 成都 | 劉婷 |
| 海南 | 謝濤 |
| 貴州 | 王建軍 |
| 貴陽 | 黎記 |
| 重慶 | 羅敏-張建新-劉小亞 |
+--------+----------------------------+
#--有多個(gè)的自然會(huì)被用字符分隔連接起來,只有一個(gè)人的就沒有什么變化!直接顯示
案例2
需求: 比如我們要查在重慶的有哪些人? 并且把這些人的名字用逗號(hào)隔開,
以上需求跟上面的案例1 差不多 我們就加一個(gè)效果, 也就是顯示出來的名字前面把id號(hào) 也加上
#--顯示出來每一個(gè)名字所對(duì)應(yīng)的id號(hào) 這里我們結(jié)合了group_concat()函數(shù) 和 concat_ws()函數(shù),
select
paddr,
group_concat(concat_ws('-',id,pname) order by id asc) as '人'
from per
group by paddr;
#--顯示結(jié)果
+--------+-----------------------------------+
| paddr | 人 |
+--------+-----------------------------------+
| 上海 | 2-張文軍,9-張良,11-趙小麗 |
| 北京 | 1-王小華,12-張三 |
| 成都 | 5-劉婷 |
| 海南 | 8-謝濤 |
| 貴州 | 7-王建軍 |
| 貴陽 | 10-黎記 |
| 重慶 | 3-羅敏,4-張建新,6-劉小亞 |
+--------+-----------------------------------+
注意:
- MySQL中函數(shù)是可以嵌套使用的
- 一般使用group_concat()函數(shù),必須是存在group by 分組的情況下 才能使用這個(gè)函數(shù)
案例3
我們?cè)賮砜匆粋€(gè)案例, 首先我們準(zhǔn)備以下測(cè)試數(shù)據(jù)
準(zhǔn)備一個(gè)student學(xué)生表田晚、MySQL代碼如下
#-- student
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT, #--id
`stuName` varchar(22) DEFAULT NULL, #--學(xué)生姓名
`course` varchar(22) DEFAULT NULL, #--學(xué)習(xí)科目
`score` int(11) DEFAULT NULL, #--學(xué)分
PRIMARY KEY (`id`) #--設(shè)置主鍵
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; #--設(shè)置表引擎 自動(dòng)遞增起始值 默認(rèn)編碼格式
-- ----------------------------
-- 插入以下數(shù)據(jù)
-- ----------------------------
INSERT INTO `student`(stuName,course,score) VALUES ('張三', '語文', '91');
INSERT INTO `student`(stuName,course,score) VALUES ('張三', '數(shù)學(xué)', '90');
INSERT INTO `student`(stuName,course,score) VALUES ('張三', '英語', '87');
INSERT INTO `student`(stuName,course,score) VALUES ('李四', '語文', '79');
INSERT INTO `student`(stuName,course,score) VALUES ('李四', '數(shù)學(xué)', '95');
INSERT INTO `student`(stuName,course,score) VALUES ('李四', '英語', '80');
INSERT INTO `student`(stuName,course,score) VALUES ('王五', '語文', '77');
INSERT INTO `student`(stuName,course,score) VALUES ('王五', '數(shù)學(xué)', '81');
INSERT INTO `student`(stuName,course,score) VALUES ('王五', '英語', '89');
#--建立好之后 數(shù)據(jù)如下顯示:
mysql> select * from student;
+----+---------+--------+-------+
| id | stuName | course | score |
+----+---------+--------+-------+
| 10 | 張三 | 語文 | 91 |
| 11 | 張三 | 數(shù)學(xué) | 90 |
| 12 | 張三 | 英語 | 87 |
| 13 | 李四 | 語文 | 79 |
| 14 | 李四 | 數(shù)學(xué) | 95 |
| 15 | 李四 | 英語 | 80 |
| 16 | 王五 | 語文 | 77 |
| 17 | 王五 | 數(shù)學(xué) | 81 |
| 18 | 王五 | 英語 | 89 |
+----+---------+--------+-------+
建立好表和數(shù)據(jù)之后 我們就來繼續(xù)使用group_concat()函數(shù) 加深以下印象!
需求1: 以stuName學(xué)生名稱分組嘱兼,把得分?jǐn)?shù)score字段的值打印在一行,逗號(hào)分隔(默認(rèn)) SQL如下
select stuName, GROUP_CONCAT(score) as '當(dāng)前這個(gè)學(xué)生的得分?jǐn)?shù)' from student GROUP BY stuName;
#--運(yùn)行結(jié)果如下
mysql> select stuName, GROUP_CONCAT(score) as '當(dāng)前這個(gè)學(xué)生的得分?jǐn)?shù)' from student GROUP BY stuName;
+---------+--------------------------------+
| stuName | 當(dāng)前這個(gè)學(xué)生的得分?jǐn)?shù) |
+---------+--------------------------------+
| 張三 | 91,90,87 |
| 李四 | 79,95,80 |
| 王五 | 77,81,89 |
+---------+--------------------------------+
需求2: 那么根據(jù)上面的結(jié)果 我們看到分?jǐn)?shù)是出來了 但是不知道是什么科目分?jǐn)?shù) 那么我們還要把科目也連起來顯示,并且分?jǐn)?shù)還是從小到大,我們應(yīng)該怎么做呢 ? 其實(shí)很簡單的啦 SQL如下
select stuName, GROUP_CONCAT(concat_ws('=',course,score) order by score asc) as '當(dāng)前這個(gè)學(xué)生的得分?jǐn)?shù)' from student GROUP BY stuName;
#--執(zhí)行結(jié)果如下
+---------+--------------------------------+
| stuName | 當(dāng)前這個(gè)學(xué)生的得分?jǐn)?shù) |
+---------+--------------------------------+
| 張三 | 英語=87,數(shù)學(xué)=90,語文=91 |
| 李四 | 語文=79,英語=80,數(shù)學(xué)=95 |
| 王五 | 語文=77,數(shù)學(xué)=81,英語=89 |
+---------+--------------------------------+
#-- 這樣顯示是不是覺得更加清楚了呢!
需求3: 這里再給小伙伴深入一個(gè)問題 那么我們現(xiàn)在要查詢出 語文、數(shù)學(xué)盒蟆、外語 三門課的最低分,還有哪個(gè)學(xué)生考的踢涌? 現(xiàn)在應(yīng)該怎么寫呢?
==[方法1]==
#--首先我們可以把這個(gè)問題拆分成兩個(gè)部分
#--1.就是找出語文、數(shù)學(xué)序宦、外語 三門課的最低分 這一步還是比較簡單的我們可以使用分組查詢就可以解決
#--分析問題后得出SQL方案 按照科目進(jìn)行分組查詢 然后使用聚合函數(shù)篩選出最小的得分?jǐn)?shù), 顯示對(duì)應(yīng)科目字段 這樣就得出了三門課的最低分
SELECT min(score),course FROM student GROUP BY course;
#--那么查詢出的結(jié)果如下
+------------+--------+
| min(score) | course |
+------------+--------+
| 81 | 數(shù)學(xué) |
| 80 | 英語 |
| 77 | 語文 |
+------------+--------+
#--那么接下來我們要考慮的是如何找到是哪個(gè)學(xué)生考的!?
#--這里我們可以使用in() 的包含+ 子查詢的方式來 根據(jù)上面SQL的結(jié)果 來進(jìn)行匹配包含查詢 學(xué)生名
SELECT stuName,score,course from student where (score,course) in(SELECT min(score),course FROM student GROUP BY course);
#--結(jié)果如下
+---------+-------+--------+
| stuName | score | course |
+---------+-------+--------+
| 李四 | 80 | 英語 |
| 王五 | 77 | 語文 |
| 王五 | 81 | 數(shù)學(xué) |
+---------+-------+--------+
問題分析
- 這里的重點(diǎn)就在于子查詢的使用 上面已經(jīng)用一句SQL查詢出了 三門課的最低分和科目 那么我們就可以列用這個(gè)結(jié)果集來 當(dāng)做另外一句SQL所要查詢條件 !
- where 后面跟的是一個(gè)圓括號(hào) 里面寫的是 分?jǐn)?shù)和科目兩個(gè)字段睁壁,用來匹配in() 里面的子查詢結(jié)果 可能這里有些新手小伙伴并沒有見過這樣寫 現(xiàn)在應(yīng)該清楚了
==[方法2]==
#--我們也可以用以下SQL語句來實(shí)現(xiàn) ,性能上比上面好一點(diǎn)點(diǎn)!
SELECT g.`id`,g.`course`,g.`score`,g.`stuName`FROM (SELECT course, SUBSTRING_INDEX(GROUP_CONCAT(score ORDER BY score ASC), ',',1) AS score FROM student GROUP BY course) AS t LEFT JOIN student AS g ON (t.course = g.`course` AND t.score = g.`score`)
#--小提示:SUBSTRING_INDEX() 函數(shù)是提取的連接字符中的第一個(gè)
#--簡單的說 先連接好分?jǐn)?shù)字段中的得分默認(rèn)用逗號(hào) 再從分?jǐn)?shù)連接字符中提取第一個(gè)出來,
#--首先我們要得到每一個(gè)科目中最小的分?jǐn)?shù) 我們可以分析出如下SQL,
#--這里的分組條件還是以科目進(jìn)行分組, 分組之后還是GROUP_CONCAT()函數(shù)用逗號(hào)連接起相對(duì)應(yīng)的所有分?jǐn)?shù),然后用SUBSTRING_INDEX()函數(shù)提取連接字符中的第一個(gè)字符作為結(jié)果
SELECT course,SUBSTRING_INDEX(GROUP_CONCAT(score ORDER BY score ASC),',',1) AS score FROM student GROUP BY course;
#--結(jié)果如下
+--------+-------+
| course | score |
+--------+-------+
| 數(shù)學(xué) | 81 |
| 英語 | 80 |
| 語文 | 77 |
+--------+-------+
#--我們可以把這個(gè)結(jié)果 想象成一張?zhí)摂M表取一個(gè)別名 t, 現(xiàn)在t這個(gè)是一個(gè)臨時(shí)的表挨厚,我們要查詢id,科目,分?jǐn)?shù),姓名, 就在前面加上需要的字段,注意別名
#--然后再使用左連接篩選出 對(duì)應(yīng)的結(jié)果
SELECT g.`id`,g.`course`,g.`score`,g.`stuName`FROM
(SELECT course,SUBSTRING_INDEX(GROUP_CONCAT(score ORDER BY score ASC),',',1) AS score FROM student GROUP BY course) as t
LEFT JOIN student AS g ON (t.course = g.`course` AND t.score = g.`score`) #--left join 來顯示出符合條件的結(jié)果 也就是用上面查詢出來的結(jié)果來對(duì)應(yīng)條件
#--結(jié)果如下
+------+--------+-------+---------+
| id | course | score | stuName |
+------+--------+-------+---------+
| 15 | 英語 | 80 | 李四 |
| 16 | 語文 | 77 | 王五 |
| 17 | 數(shù)學(xué) | 81 | 王五 |
+------+--------+-------+---------+
案例4
我們來簡單的準(zhǔn)備一個(gè)商品表吧 , 代碼如下
#-- goods
CREATE TABLE `goods` (
`id` int(11) NOT NULL AUTO_INCREMENT, #--id
`price` varchar(22) DEFAULT NULL, #--商品價(jià)格
`goods_name` varchar(22) DEFAULT NULL, #--商品名稱
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; #--設(shè)置表引擎 自動(dòng)遞增起始值 默認(rèn)編碼格式
-- ----------------------------
-- 插入以下數(shù)據(jù)
-- ----------------------------
INSERT INTO `goods`(price,goods_name) VALUES (10.00, '皮包');
INSERT INTO `goods`(price,goods_name) VALUES (20.00, '圍巾');
INSERT INTO `goods`(price,goods_name) VALUES (30.00, '圍巾');
INSERT INTO `goods`(price,goods_name) VALUES (40.00, '游戲機(jī)');
INSERT INTO `goods`(price,goods_name) VALUES (60.00, '皮包');
INSERT INTO `goods`(price,goods_name) VALUES (80.00, '游戲機(jī)');
INSERT INTO `goods`(price,goods_name) VALUES (220.00, '游戲機(jī)');
INSERT INTO `goods`(price,goods_name) VALUES (780.00, '圍巾');
INSERT INTO `goods`(price,goods_name) VALUES (560.00, '游戲機(jī)');
INSERT INTO `goods`(price,goods_name) VALUES (30.00, '皮包');
需求1: 以 商品名稱分組堡僻,把price字段的值在一行打印出來,分號(hào)分隔
select goods_name,group_concat(price) from goods group by goods_name;
需求2: 以 商品名稱分組疫剃,把price字段的值在一行打印出來钉疫,分號(hào)分隔 并且去除重復(fù)冗余的價(jià)格字段的值
select goods_name,group_concat(distinct price) from goods group by goods_name;
需求3: 以 商品名稱分組,把price字段的值在一行打印出來巢价,分號(hào)分隔 去除重復(fù)冗余的價(jià)格字段的值 并且排序 從小到大
select goods_name,group_concat(distinct price order by price desc) from goods group by goods_name; #--錯(cuò)誤的
select goods_name,group_concat(distinct price order by price+1 desc) from goods group by goods_name; #--正確的
#--注意以上存在隱式數(shù)據(jù)類型轉(zhuǎn)換 如果不這樣轉(zhuǎn)換排序出來的結(jié)果是錯(cuò)誤的 , 因?yàn)槲冶4鎝rice價(jià)格的字段是varchar類型的
案例5
我們?cè)俳Y(jié)合group_concat()函數(shù)來做一個(gè)多表查詢的案例
準(zhǔn)備 三張 測(cè)試數(shù)據(jù)表: 用戶表[user]牲阁、水果表[fruit]固阁、用戶喜歡哪些水果的表[user_like]
首先 建立用戶表[user] SQL語句代碼如下
#-- user
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT, #--id
`username` varchar(22) DEFAULT NULL, #--用戶名
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; #--設(shè)置表引擎 自動(dòng)遞增起始值 默認(rèn)編碼格式
#--插入測(cè)試數(shù)據(jù)
INSERT INTO `user`(username) VALUES ('張三');
INSERT INTO `user`(username) VALUES ('李四');
INSERT INTO `user`(username) VALUES ('王文玉');
建立水果表[fruit] SQL語句代碼如下
#-- fruit
CREATE TABLE `fruit` (
`id` int(11) NOT NULL AUTO_INCREMENT, #--id
`fruitname` varchar(22) DEFAULT NULL, #--水果名稱
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; #--設(shè)置表引擎 自動(dòng)遞增起始值 默認(rèn)編碼格式
#--插入測(cè)試數(shù)據(jù)
INSERT INTO `fruit`(fruitname) VALUES ('西瓜');
INSERT INTO `fruit`(fruitname) VALUES ('蘋果');
INSERT INTO `fruit`(fruitname) VALUES ('芒果');
INSERT INTO `fruit`(fruitname) VALUES ('梨');
INSERT INTO `fruit`(fruitname) VALUES ('葡萄');
建立 用戶喜愛表 [user_like]
但是建立這個(gè)表的時(shí)候 跟前面兩個(gè)表有所不同,小伙們們首先要搞清楚 這個(gè)表是一個(gè)什么用來干啥的表
分析清楚這個(gè)表的關(guān)系城菊, 因?yàn)槭怯脩粝矚g哪些水果的表 那么 一個(gè)水果可以被多個(gè)用戶所喜歡對(duì)吧? 反過來說一個(gè)用戶也可以喜歡多個(gè)水果吧 對(duì)吧 那么這里是一個(gè)什么關(guān)系呢 备燃?? 很明顯是一個(gè) 多對(duì)多的關(guān)系!
所以建立這個(gè)表 我們就可以使用 用戶的id 來對(duì)應(yīng) 水果的id 就可以實(shí)現(xiàn)一個(gè)中間連接多對(duì)多的表了
SQL語句代碼如下:
#-- fruit
CREATE TABLE `user_like` (
`id` int(11) NOT NULL AUTO_INCREMENT, #--id
`user_id` int, #--用戶的id號(hào)
`fruit_id` int, #--水果的id號(hào)
CONSTRAINT user_like PRIMARY KEY (id,user_id,fruit_id) #--定義聯(lián)合主鍵 讓每一條記錄唯一
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; #--設(shè)置表引擎 自動(dòng)遞增起始值 默認(rèn)編碼格式
#--測(cè)試數(shù)據(jù)
INSERT INTO `user_like`(user_id,fruit_id) VALUES (1,1); #--這就代表用戶表中id號(hào)為1的用戶 喜歡fruit表中id號(hào)為1的水果
INSERT INTO `user_like`(user_id,fruit_id) VALUES (1,2); #--這就代表用戶表中id號(hào)為1的用戶 喜歡fruit表中id號(hào)為2的水果
INSERT INTO `user_like`(user_id,fruit_id) VALUES (1,3); #--這就代表用戶表中id號(hào)為1的用戶 喜歡fruit表中id號(hào)為3的水果
INSERT INTO `user_like`(user_id,fruit_id) VALUES (2,3); #--這就代表用戶表中id號(hào)為2的用戶 喜歡fruit表中id號(hào)為3的水果
INSERT INTO `user_like`(user_id,fruit_id) VALUES (2,4); #--這就代表用戶表中id號(hào)為2的用戶 喜歡fruit表中id號(hào)為4的水果
INSERT INTO `user_like`(user_id,fruit_id) VALUES (2,5); #--這就代表用戶表中id號(hào)為2的用戶 喜歡fruit表中id號(hào)為5的水果
INSERT INTO `user_like`(user_id,fruit_id) VALUES (3,5); #--這就代表用戶表中id號(hào)為3的用戶 喜歡fruit表中id號(hào)為5的水果
INSERT INTO `user_like`(user_id,fruit_id) VALUES (3,1); #--這就代表用戶表中id號(hào)為3的用戶 喜歡fruit表中id號(hào)為1的水果
INSERT INTO `user_like`(user_id,fruit_id) VALUES (3,2); #--這就代表用戶表中id號(hào)為3的用戶 喜歡fruit表中id號(hào)為2的水果
#-- 以此類推...
好了 現(xiàn)在數(shù)據(jù) 和 表我們都已經(jīng)準(zhǔn)備好了 , 那么 接下來 我們就要開始進(jìn)行 GROUP_CONCAT()函數(shù)的使用了
需求: 查出每個(gè)用戶喜歡的水果都有哪些!
#--查詢SQL如下
select u.username,group_concat(f.fruitname) from user_like as c inner join user as u on c.user_id=u.id inner join fruit as f on c.fruit_id=f.id group by c.user_id;
#--結(jié)果如下
+-----------+---------------------------+
| username | group_concat(f.fruitname) |
+-----------+---------------------------+
| 張三 | 芒果,蘋果 |
| 李四 | 梨,芒果,葡萄 |
| 王文玉 | 西瓜,葡萄,蘋果 |
+-----------+---------------------------+
如果我的博客對(duì)你有幫助凌唬、如果你喜歡我的博客內(nèi)容并齐,請(qǐng) “點(diǎn)贊” “評(píng)論” “收藏”
一鍵三連哦!
如果以上內(nèi)容有任何錯(cuò)誤或者不準(zhǔn)確的地方客税,歡迎在下面 ?? 留個(gè)言指出况褪、或者你有更好的想法,歡迎一起交流學(xué)習(xí)