MySQL新学知识(一)

MySQL新学知识(一)


前言

👨‍💻👨‍🌾📝记录学习成果,以便温故而知新 本专题把一阶段学到知识MySQL做一个总结


本篇的4项是最近学习的,有的以前可能看到过,但是并没有深入学习了解,这次对照文档稍微深入地学习了一下。在MySQL文档中归属于Built-In Function and Operator Reference和Aggregate Functions下的GROUP BY Modifiers。其中有的功能5.7是支持的,有的功能要到8才支持,需要注意。

一、3个函数

1.COALESCE

MySQL文档https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#function_coalesce

功能说明如下:

Returns the first non-NULL value in the list, or NULL if there are no non-NULL values.

The return type of COALESCE() is the aggregated type of the argument types.

很简短,意思也不难理解,就不翻译了。

示例如下:

mysql> SELECT COALESCE(NULL,1);

-> 1

mysql> SELECT COALESCE(NULL,NULL,NULL);

-> NULL

也很简短。

以前要是想实现这样的功能,一般都是用 CASE WHEN 来实现的。现在有了COALESCE,很简短。

以上只能说是"一顾倾人城",用在表连接上才是"再顾倾人国"。

假定有x、y与z三个作业表,其中y表的in_id是x表的out_id,z表的in_id是y表的out_id或x表的out_id。

x表结构与数据如下:

sql 复制代码
CREATE TABLE `x` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `in_id` varchar(100) DEFAULT NULL COMMENT '输入ID',
  `out_id` varchar(100) DEFAULT NULL COMMENT '输出ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
id in_id out_id
1 T1 T1X1
2 T2 T2X1
3 T2 T2X2
4 T3 T3X1
5 T4 T4X1

y表结构与数据如下:

sql 复制代码
CREATE TABLE `y` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `in_id` varchar(100) DEFAULT NULL COMMENT '输入ID',
  `out_id` varchar(100) DEFAULT NULL COMMENT '输出ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
id in_id out_id
1 T1X1 T1X1Y1
2 T2X1 T2X1Y1

y表结构与数据如下:

sql 复制代码
CREATE TABLE `z` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `in_id` varchar(100) DEFAULT NULL COMMENT '输入ID',
  `out_id` varchar(100) DEFAULT NULL COMMENT '输出ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
id in_id out_id
1 T1X1Y1 T1X1Y1Z1
2 T3X1 T3X1Z1
3 T4X1 T4X1Z1
4 T4X1 T4X1Z2

对x、y与z表做关联查询SQL如下:

sql 复制代码
SELECT x.id AS X_ID, x.in_id AS X_IN_ID, x.out_id AS X_OUT_ID,
y.id AS Y_ID, y.in_id AS Y_IN_ID, y.out_id AS Y_OUT_ID,
z.id AS Z_ID, z.in_id AS Z_IN_ID, z.out_id AS Z_OUT_ID
FROM x LEFT JOIN y ON x.out_id = y.in_id LEFT JOIN z ON COALESCE(y.out_id, x.out_id) = z.in_id
ORDER BY x.id

查询结果如下图:

对于上述业务模式,COALESCE用在表关联上使得查询语句变得很简洁。

2.GROUP_CONCAT

MySQL文档https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat

功能说明如下:

This function returns a string result with the concatenated non-NULL values from a group. It returns NULL if there are no non-NULL values

语法如下:

GROUP_CONCAT([DISTINCT] expr [,expr ...]

ORDER BY {unsigned_integer \| col_name \| expr} \[ASC \| DESC\] \[,col_name ...\]

SEPARATOR str_val\]) **The result is truncated to the maximum length that is given by the group_concat_max_len system variable, which has a default value of 1024.**

这里借用下面WITH ROLLUP这节的sales表来举例说明,因为sales是MySQL文档中WITH ROLLUP章节自带的,用在这里也挺合适。

(1)先来一个简单的SQL如下:

sql 复制代码
SELECT year, GROUP_CONCAT(country) AS country
FROM sales
GROUP BY year;

查询结果如下图:

country列中有重复值。

(2)再来一个SQL去掉country列中重复值如下:

sql 复制代码
SELECT year, GROUP_CONCAT(DISTINCT country) AS country
FROM sales
GROUP BY year;

查询结果如下图:

(4)在简单的SQL的基础上根据profit排序如下:

sql 复制代码
SELECT year, GROUP_CONCAT(country ORDER BY profit DESC) AS country
FROM sales
GROUP BY year;

查询结果如下图:

(5)在简单的SQL的基础上先排序后去重如下:

sql 复制代码
SELECT year, GROUP_CONCAT(DISTINCT country ORDER BY country DESC) AS country
FROM sales
GROUP BY year;

查询结果如下图:

3.ROW_NUMBER

MySQL文档https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html#function_row-number

这里还是借用下面WITH ROLLUP这节的sales表来举例说明。

sql 复制代码
SELECT
ROW_NUMBER() OVER w AS 'row_number',sales.*
FROM sales
WINDOW w AS (ORDER BY profit);

查询结果如下图:

效果是有的,但是还需要增加一个"WINDOW",使得语句变得复杂起来了。

二、GROUP聚合的附带功能

1.WITH ROLLUP

MySQL文档https://dev.mysql.com/doc/refman/8.0/en/group-by-modifiers.html

文档中附带一个表用来说明功能。建表语句如下:

sql 复制代码
CREATE TABLE sales
(
    year    INT,
    country VARCHAR(20),
    product VARCHAR(32),
    profit  INT
);

表内容如下:

year country product profit
2000 Finland Computer 1500
2000 Finland Phone 100
2000 India Calculator 150
2000 India Computer 1200
2000 USA Calculator 75
2000 USA Computer 1500
2001 Finland Phone 10
2001 USA Calculator 50
2001 USA Computer 2700
2001 USA TV 250

WITH ROLLUP的功能就是加在GROUP BY子句后生成额外的汇总行,文档中的内容翻译起来感觉很拗口,就直接看下面的效果。

先看不加WITH ROLLUP的效果,语句如下:

sql 复制代码
SELECT year, SUM(profit) AS profit
FROM sales
GROUP BY year;

查询结果如下图:

加WITH ROLLUP的效果,语句如下:

sql 复制代码
SELECT year, SUM(profit) AS profit
FROM sales
GROUP BY year WITH ROLLUP;

查询结果如下图:

与不加WITH ROLLUP相比,多出了一行。

再看一个GROUP BY子句中3列情况,作为对比,先看不加WITH ROLLUP的效果,语句如下:

sql 复制代码
SELECT year, country, product, SUM(profit) AS profit
FROM sales
GROUP BY year, country, product;

查询结果如下图:

加WITH ROLLUP的效果,语句如下:

sql 复制代码
SELECT year, country, product, SUM(profit) AS profit
FROM sales
GROUP BY year, country, product WITH ROLLUP;

查询结果如下图:

与不加WITH ROLLUP相比,多出了8行。

2组查询对比,感觉是GROUP BY子句中的列从右到左,每列在聚合的基础上再汇总。

2.GROUPING

GROUPING是一个函数,配合WITH ROLLUP用的。本文只简单介绍一下WITH ROLLUP文档中部分,更多GROUPING用法请参考GROUPING文档

MySQL文档中如下语句:

sql 复制代码
SELECT
year, country, product, SUM(profit) AS profit,
GROUPING(year) AS grp_year,
GROUPING(country) AS grp_country,
GROUPING(product) AS grp_product
FROM sales
GROUP BY year, country, product WITH ROLLUP;

查询结果如下图:

结果很显然如果参数是null返回1;其它返回0.

感觉作用并不明显,MySQL文档中如下的SQL能够体现出WITH ROLLUP的作用

sql 复制代码
SELECT
IF(GROUPING(year), 'All years', year) AS year,
IF(GROUPING(country), 'All countries', country) AS country,
IF(GROUPING(product), 'All products', product) AS product,
SUM(profit) AS profit
FROM sales
GROUP BY year, country, product WITH ROLLUP;

查询结果如图:

相关推荐
苏小瀚1 天前
[MySQL] 事务和视图
数据库·mysql·1024程序员节
刺客-Andy1 天前
Python 第二十节 正则表达式使用详解及注意事项
python·mysql·正则表达式
哈__1 天前
MongoDB 平替新方案:金仓多模数据库驱动电子证照国产化落地
数据库·1024程序员节
微学AI1 天前
国产数据库替代MongoDB的技术实践过程:金仓多模数据库在电子证照系统中的深度应用
数据库·人工智能·1024程序员节
TDengine (老段)1 天前
TDengine 数据函数 ROUND 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·1024程序员节
TDengine (老段)1 天前
TDengine 数学函数 RAND 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
野犬寒鸦1 天前
从零起步学习MySQL || 第十章:深入了解B+树及B+树的性能优势(结合底层数据结构与数据库设计深度解析)
java·数据库·后端·mysql·1024程序员节
GZ_TOGOGO1 天前
Oracle OCP考试报名常见问题详解
数据库·oracle·ocp认证
睡不醒的猪儿1 天前
nginx日志同步阿里云datahub后写入数据库
数据库·nginx·阿里云
xie_zhr1 天前
【PB案例学习笔记】-46在数据窗口中编辑数据
数据库·his·1024程序员节·干货分享·pb·powerbuilder