模拟 GROUP_CONCAT() 函数
时间:2022-07-22
本文章向大家介绍模拟 GROUP_CONCAT() 函数,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
MySQL 提供了 GROUP_CONCAT()
函数,可以很方便地针对某字段下的值聚合成一个字符串,字符串内部默认使用“,”分割。
比如,我们要将 emp
表中每个部门的员工的姓名聚合到一起,就这么写 SQL :
SELECT
deptno,
GROUP_CONCAT(ename) AS enames
FROM
emp
GROUP BY deptno
聚合到一起的结果如下:
deptno enames
------ --------------------------------------
10 MILLER,KING,CLARK
20 FORD,ADAMS,SCOTT,JONES,SMITH
30 BLAKE,MARTIN,TURNER,WARD,JAMES,ALLEN
如果没有 GROUP_CONCAT()
函数,我们怎么实现聚合的效果呢?
答案是使用用户变量!使用用户变量可以做到看似将整张表的数据按行处理的效果。
为了让大家看清使用了用户变量的处理过程,我把实现的步骤拆分成两部分。
先来看部门中的员工姓名是怎么聚合到一块:
SELECT
deptno,
@ename := IF(
deptno = @deptno,
CONCAT_WS(',', @ename, ename),
ename
) AS enames,
@deptno := deptno
FROM
emp,
(SELECT
@deptno := NULL,
@ename := '') AS t
ORDER BY deptno
这步操作的输出如下:
deptno enames @deptno := deptno
------ ------------------------------- ------------
10 MILLER 10
10 MILLER,KING 10
10 MILLER,KING,CLARK 10
20 FORD 20
20 FORD,ADAMS 20
20 FORD,ADAMS,SCOTT 20
20 FORD,ADAMS,SCOTT,JONES 20
20 FORD,ADAMS,SCOTT,JONES,SMITH 20
30 BLAKE 30
30 BLAKE,MARTIN 30
30 BLAKE,MARTIN,TURNER 30
30 BLAKE,MARTIN,TURNER,WARD 30
30 BLAKE,MARTIN,TURNER,WARD,JAMES 30
30 BLAKE,MARTIN,TURNER,WARD,JAMES,ALLEN 30
从上面的结果可以看出,在每个分组里,员工姓名在不断组合,enames
也就越来越长。
最后,去掉中间过程生成的结果,只把最终的结果展现出来。
SELECT
deptno,
MAX(enames) AS enames
FROM
(SELECT
deptno,
@ename := IF(
deptno = @deptno,
CONCAT_WS(',', @ename, ename),
ename
) AS enames,
@deptno := deptno
FROM
emp,
(SELECT
@deptno := NULL,
@ename := '') AS t
ORDER BY deptno) t
GROUP BY deptno
在 SQL 里使用 CONCAT_WS()
函数将多个值拼接成一个字符串,最后使用 GROUP BY + MAX()
取出每个分组里面最长的字符串。
只是需要注意一个地方,用户变量 @ename
的初始值一定设置成 ''
,而不能是 NULL
,因为 NULL
和其它字符串拼接还是 NULL
。
另外,使用 GROUP_CONCAT()
需要注意两个地方:
-
GROUP_CONCAT()
聚合的结果有长度限制,默认是 1024,要想支持更长的聚合结果,可以修改group_concat_max_len
变量。 - 聚合的结果并不是有序的,比如对于
a
、b
、c
三个值,聚合后不一定就是abc
。要保证有序可以设在GROUP_CONCAT()
内部指定排序方式。
比如,要想把最后的结果按照内部值的首字母进行顺序排序,就可以这么做:
SELECT
deptno,
GROUP_CONCAT(ename
ORDER BY ename) AS enames
FROM
emp
GROUP BY deptno
输出如下:
deptno enames
------ -------------------------
10 CLARK,KING,MILLER
20 ADAMS,FORD,JONES,SCOTT,SMITH
30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD
用户变量改一下排序字段也可以达到这种效果:
SELECT
deptno,
MAX(enames) AS enames
FROM
(SELECT
deptno,
@ename := IF(
deptno = @deptno,
CONCAT_WS(',', @ename, ename),
ename
) AS enames,
@deptno := deptno
FROM
emp,
(SELECT
@deptno := NULL,
@ename := '') AS t
ORDER BY deptno,ename) t
GROUP BY deptno
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- R语言Black Scholes和Cox-Ross-Rubinstein期权定价模型案例
- R语言中的风险价值模型度量指标TVaR与VaR
- R语言用线性回归模型预测空气质量臭氧数据
- R语言线性模型臭氧预测: 加权泊松回归,普通最小二乘,加权负二项式模型
- R语言中回归和分类模型选择的性能指标
- R语言 线性混合效应模型实战案例
- R语言中敏感性和特异性、召回率和精确度作为选型标准的华夫图案例
- R语言中的多类别问题的绩效衡量:F1-score 和广义AUC
- Dart语言基础Map、List、Set操作合辑
- 2.2.2 类反射场景与使用 -《SSM深入解析与项目实战》
- 每天手撕一道算法-64. 最小路径和
- Flutter 1.20 下的 Hybrid Composition 深度解析
- Flutter 1.17 对列表图片的优化解析
- SQL注入常用函数和关键字总结
- 用遗传算法求解函数