1 SQL基础概念
SQL解释:结构化的查询语言,关系型数据库的通用命令,遵循SQL92的标准
1.1 SQL常用的几种分类
DDL:数据定义语言
DCL:控制语言
DML:操作语言
DQL:查询语言
1.2 数据库的库与表的逻辑结构
库
库名字
库属性:字符集,排序规则
表
表名
表属性:存储引擎类型,字符集,排序规则
列名
列属性:数据类型,约束,其他属性
数据行
1.3 字符集(charset)
相当于MySQL的密码本(编码本)
show charset; 查看字符集
utf8 3个字节
utf8mb4 4个字节,支持emoji(工作中建议使用此字符集,8.0开始默认使用此字符集)
排序规则:collation
show collation;
对于英文字符串的,大小写的敏感
uft8mb4_general_ci 大小写不敏感
utf8mb4_bin 大小写敏感(存拼音,日文)
1.4 数据类型
1)数字
整数
tinyint:极小整数(0-255),
int:-2^31至2^31-1
浮点数
2)字符串
char(100) 定长的字符串类型,不管字符串有多长,都立即分配100个字符串长度
varchar(100)变长字符串类型,每次存储数据之前,都要先判断一下长度,按需分配磁盘空间,会单独申请一个字符串长度的空间存储字符长度(少于255,如果超过255以上,会占用两个存储空间)
如何选择这两个数据类型?
1.少于255个字符长度,定长的列值,选择char
2.多于255字符串长度,变长的字符串,可以选择varchar
enum 枚举数据类型
如星期一到星期天,月份类似这种可列举的数据
以上三种数据类型对索引的性能影响比较大
3)时间
DATETIME
范围为从 1000-01-01 00:00:00.000000 至 9999-12-31 23:59:59.999999。
TIMESTAMP
1970-01-01 00:00:00.000000 至 2038-01-19 03:14:07.999999,timestamp会受到时区的影响
4)二进制:略
2 DDL语句的应用
2.1 DDL语句之库的定义
2.1.1 库定义的规范
1、库名使用小写字符
2、库名不能以数字开头
3、不能是数据库内部的关键字
4、必须设置字符集
2.2.2 库定义
1)创建库
db01 [(none)]>create database zabbix charset uft8mb4 collate uft8mb4_bin;
2)查看库(show不属于DDL)
db01 [(none)]>show databases;
查看如何创建该数据库的
db01 [(none)]>show create database zabbix;
3)删除库(不代表生产操作)
db01 [(none)]>drop database zabbix;
4)修改数据库字符集,注意:一定是从小往大了改,比如utf8—>utf8mb4,目标字符集是源字符集的超集
db01 [(none)]>alter database zabbix charset utf8mb4;
2.2 DDL语句之表的定义
2.2.1 建表规范
1)建表规范
1.表名小写字母,不能数字开头
2.不能是保留字符,使用和业务相关的表名
3.选择合适的数据类型和长度
4.每个列设置not null + DEFAULT 对于数据0填充,对于字符使用有效字符
5.每个列设置注释
6.主键列尽量是无关列数字列,最好是自增长
7.enum类型不要保存数字,只能是字符串类型
2)建表
表名、列名、列属性、表属性
3)列属性
PRIMARY KEY:主键约束,表中只能有一个,非空且唯一,主键又分为单列主键和联合组件
mysql> create table t1(id int not null auto_increment,name varchar(20),primary key(id,name));
NOT NULL:非空约束,必填项,不允许为空值
UNIQUE KEY:唯一键约束,不允许重复值
DEFAULT:一般配合NOT NULL一起使用
UNSIGNED:无符号,一般是配合数字列,非负数
COMMENT:注释
AUTO_INCREMENT:自增长的列
2.2.2 表定义
1)在zabbix下创建一张stu的表
CREATE TABLE zabbix.stu(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '学号',
sname VARCHAR(255) NOT NULL COMMENT '姓名',
age TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '年龄',
gender ENUM('m','f','n') NOT NULL DEFAULT 'n' COMMENT "性别",
intime DATETIME NOT NULL DEFAULT NOW() COMMENT '入学时间'
)ENGINE INNODB CHARSET utf8mb4;
DESC stu;
2)查询建表信息
db01 [zabbix]>show tables;
db01 [zabbix]>show create table stu;
3)创建一张表结构跟stu一样的表
db01 [zabbix]>create table test like stu;
db01 [zabbix]>desc stu;
4)删表
db01 [zabbix]>drop table test;
5)修改
a、在stu表中添加qq列
db01 [zabbix]>desc stu;
db01 [zabbix]>alter table stu add qq varchar(20) not null comment ‘qq号’;
备注:不要轻易执行此操作,会存在锁表的情况,导致业务出现问题,通过PT-OSC(percona-toolkits online schema change)工具可解决此问题,8.0版本已内置解决此问题
b、在sname后加微信列
db01 [zabbix]>ALTER TABLE stu ADD wechat VARCHAR(64) NOT NULL UNIQUE COMMENT ‘微信’ AFTER sname;
c、在id列前面加一个新列num
db01 [zabbix]>ALTER TABLE stu ADD num INT NOT NULL UNIQUE COMMENT ‘身份证’ FIRST;
d、把刚才添加的列都删除掉
db01 [zabbix]>ALTER TABLE stu DROP num;
db01 [zabbix]>ALTER TABLE stu DROP qq;
db01 [zabbix]>ALTER TABLE stu DROP wechat;
db01 [zabbix]>DESC stu;
e、修改sname数据类型的属性
db01 [zabbix]>desc stu;
db01 [zabbix]>alter table stu modify sname varchar(64) not null comment ‘姓名’;
f、将sgender 改为sex 数据类型改为char类型
db01 [zabbix]>alter table stu change gender sex char(4) not null comment ‘性别’;
3 DCL语句的应用
grant、revoke
1、grant
mysql> grant all on . to root@’10.0.0.1%’ identified by ‘abc123..’;
2、revoke
mysql> revoke delete on . from ‘xiang’@’10.0.0.%’;
4 DML语句的应用
4.1 DML之insert
desc stu;
1)最偷懒方式
db01 [zabbix]>insert into stu values (1,’zs’,18,’m’,now());
db01 [zabbix]> select from stu;
2)规范方式
db01 [zabbix]>insert into stu(id,sname,age,sex,intime) values(2,’ls’,19,’f’,now());
3)针对性的录入数据
db01 [zabbix]>insert into stu(sname,age,sex) values(‘w5’,11,’m’);
*4)一次性录入多行
db01 [zabbix]>insert into stu(sname,age,sex)values(‘aaa’,11,’f’),(‘bbb’,12,’f’),(‘ccc’,13,’m’);
4.2 DML之update
更新行内容
mysql> update stu set sname=”zhangshan”,age=18 where id=4;
mysql> select * from stu;
+----+-------+-----+--------+---------------------+
| id | sname | age | gender | intime |
+----+-------+-----+--------+---------------------+
| 1 | xiang | 25 | m | 2022-01-21 16:33:07 |
| 2 | shi | 19 | m | 2022-01-21 16:34:27 |
| 3 | chuan | 20 | m | 2022-01-21 16:37:10 |
| 4 | aaa | 11 | f | 2022-01-21 16:38:30 |
| 5 | bbb | 12 | m | 2022-01-21 16:38:30 |
| 6 | cccc | 16 | m | 2022-01-21 16:38:30 |
+----+-------+-----+--------+---------------------+
6 rows in set (0.00 sec)
mysql> update stu set sname="zhangshan",age=18 where id=4;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from stu;
+----+-----------+-----+--------+---------------------+
| id | sname | age | gender | intime |
+----+-----------+-----+--------+---------------------+
| 1 | xiang | 25 | m | 2022-01-21 16:33:07 |
| 2 | shi | 19 | m | 2022-01-21 16:34:27 |
| 3 | chuan | 20 | m | 2022-01-21 16:37:10 |
| 4 | zhangshan | 18 | f | 2022-01-21 16:38:30 |
| 5 | bbb | 12 | m | 2022-01-21 16:38:30 |
| 6 | cccc | 16 | m | 2022-01-21 16:38:30 |
+----+-----------+-----+--------+---------------------+
6 rows in set (0.00 sec)
4.3 DML之delete
删除某行数据
mysql> delete from stu where id=6 ;
5DQL语句的应用
5.1 DQL之select
select通用语法
select 列
from 表
where 条件
group by 条件
having 条件
order by 条件
limit
select单独使用,查询mysql内置参数
mysql> select @@basedir;
mysql> select @@port;
mysql> select @@innodb_flush_log_at_trx_commit;
对于上面无法记住这么长的变量,可以使用帮助
mysql> show variables like “innodb%”;
mysql>select database();
mysql>select now();
lab环境的说明——-world数据库
mysql> use world;
mysql> show tables;
city 城市表
country 国家表
countrylanguage语言表
city表结构
ID : 城市序号
name : 城市名字
countrycode : 国家代码,例如中国:CHN,美国USA
district : 区域:中国 省份 美国 洲
population : 人口数
如何快速熟悉数据库业务?
1.快速和研发人员打好关系(最快速)
2.找到领导要ER图
3.desc,show create databases xxx;
4.select * from city limit 5; 看表中的数据
5.1.1 select配合from子句
语法格式:
select 列,列,列 from 表
1、查询表中所有的信息(生产中几乎是没有这种需要的)
db01 [(none)]> use world;
db01 [world]> select id,name,countrycode,district,population from city; 或者select * from city;
2、获取指定几个列的信息
db01 [world]> select id,name,countrycode from city;
5.1.2 select配合where子句
语法格式:select 列,列,列 from 表 where 过滤条件
1、where等值条件查询
查询中国所有城市名和人口数
db01 [world]> select name,population from city where countrycode=’CHN’;
2、where不等值条件查询(<> >= <=)
查询世界上小于100人的城市名和人口数
db01 [world]> select name,polulation from city where population<100;
5.1.2.1 where配合逻辑连接符(and、or)
1、查询中国人口数量大于800万的城市名和人口数
db01 [world]>select name,population from city where countrycode=’CHN’ and population>8000000;
2、查询中国或美国的城市名和人口数
db01 [world]> select name,polulation from city where countrycode=’CHN’ or countrycode=’USA’;
3、查询人口数量在500w到600之间的城市名和人口数
db01 [world]> select name,polulation from city where population>5000000 and population<6000000;
或者:
db01 [world]> select name,polulation from city where population between 5000000 and 6000000;
5.1.2.2 where配合like子句模糊查询
1、查询一下countrycode中C开头的城市信息
db01 [world]>select * from city where countrycode like “CH%”;
注意:不要出现类似于%CH%这种形式的语句,前面存在%,不走索引,性能极差,如果业务中有大量这种需求,我们用ES来代替
5.1.2.3 where配合in语句
1、查询中国或美国的城市信息
db01 [world]> select name,population from city where countrycode=’CHN’ or countrycode=’USA’;
或者
db01 [world]> select name,population from city where countrycode in (‘CHN’,’USA’);
5.1.3 select配合group by+聚合函数应用
常用函数介绍:max(),min(),avg(),count(),sum(),group_concat()
group by
将某列中有共同条件的数据行,分成一组,然后再进行聚合函数操作
列子:
1、统计每个国家,城市的个数
db01 [world]> SELECT countrycode, COUNT(id) FROM city GROUP BY countrycode;
2、统计每个国家的总人口数
db01 [world]> SELECT countrycode,SUM(population) FROM city GROUP BY countrycode;
3、统计每个国家省的个数
DISTINCT表示对相同的城市先去重再进行计数
db01 [world]> SELECT countrycode,COUNT(DISTINCT district) FROM city GROUP BY countrycode;
4、统计中国,每个省的总人口数
db01 [world]> SELECT district,SUM(population) FROM city WHERE countrycode=’CHN’ GROUP BY district;
5、统计中国,每个省城市的个数
db01 [world]> SELECT district,COUNT(NAME) FROM city WHERE countrycode=’CHN’ GROUP BY District;
6、统计中国,每个省城市的名字列表
GROUP_CONCAT
db01 [world]> SELECT district,GROUP_CONCAT(NAME) FROM city WHERE countrycode=’CHN’ GROUP BY District;
7、组合拼接显示
CONCAT
db01 [world]> SELECT CONCAT(district,”:”,GROUP_CONCAT(NAME)) FROM city WHERE countrycode=’CHN’ GROUP BY District;
5.1.4 select 配合having的使用
同where功能类似,都是做条件筛选的,只是出现的语法位置不一样,因为where只能在group by之前,因此如果想在group by之后再做一次条件筛选,就需要使用having子句,另外需要注意的是having做过滤时是不走索引的。
1、统计所有国家的总人口数量,然后将总人口数大于一亿的过滤出来显示
db01 [world]> SELECT countrycode,SUM(population) FROM city GROUP BY countrycode HAVING SUM(population)>100000000;
5.1.5 select配合order by 子句
对查询结果进行排序,默认从小到大排序,desc就是倒序排序
例子:统计所有国家的总人口数量,然后将总人口数大于5千万的过滤出来显示,并且按照从大到小的顺序进行排序
db01 [world]> SELECT countrycode,SUM(population) FROM city GROUP BY countrycode HAVING SUM(population)>50000000 ORDER BY SUM(population) DESC;
5.1.6 select配合limit 子句
分页显示,只显示指定数量的行
例子:统计所有国家的总人口数量,然后将总人口数大于5千万的过滤出来显示,并且按照从大到小的顺序进行排序,只显示前三名
db01 [world]> SELECT countrycode,SUM(population) FROM city GROUP BY countrycode HAVING SUM(population)>50000000 ORDER BY SUM(population) DESC limit 3;
limit M,N —-跳过前M行,共显示N行,如limit 3 5 指跳过前三行,显示之后的5行
limit Y offset X —-跳过X行,共显示Y行 默认就是limit N offset 0即显示N行,偏移0行
综合练习
1、统计中国每个省的总人口数,只打印总人口数小于100w的
db01 [world]> SELECT district,SUM(population) FROM city WHERE countrycode=’CHN’ GROUP BY district HAVING SUM(population)<1000000;
2、查看中国所有的城市,并按照人口数进行排序(从大到小)
db01 [world]> SELECT NAME,population FROM city WHERE countrycode=’CHN’ ORDER BY population DESC;
3、统计中国各个省的总人口数,按照总人口从大到小进行排序
db01 [world]> SELECT district,SUM(population) FROM city WHERE countrycode=’CHN’ GROUP BY district ORDER BY SUM(population) DESC;
4、统计中国每个省的总人口数,找出总人口大于500w的,并按照总人口从大到小进行排序,只显示前三名
db01 [world]> SELECT district,SUM(population) FROM city WHERE countrycode=’CHN’ GROUP BY district HAVING SUM(population)>5000000 ORDER BY SUM(population)DESC LIMIT 3;
总结:执行顺序:select from where、group by、having、order by、limit
执行逻辑分析
1、第一步:FROM city,拿到这张city表;
2、第二步:WHERE countrycode=’CHN’,条件筛选,筛选出所有符合条件的行,此处即所有countrycode=’CHN’的行;
3、第三步:GROUP BY district,对上一步执行的结果根据分组条件进行分组,此处即根据district省份进行分组;
4、第四步:SELECT district,SUM(population),执行完上面几步得到的结果,回到select之后,显示指定要查询的列值,此处即显示district,SUM(population)两列的值;
5、第五步:HAVING SUM(population)>5000000,如还有having子句,再次对上面的结果进行筛选,此处即只显示总人口大于500万人口的行
6、第六步:同理order by和limit类似,再次对上面的结果进行筛选,即排序,然后显示前面的多少行等类似需求
5.1.7 select配合union和union all
作用:是做多个结果集合并查询的功能
例子:查询中国或者美国的城市信息
db01 [world]> select from city where countrycode=’CHN’ or countrycode=’USA’;
用union all改写,这种方式比上面这种方式效率要高,因为这种方式的索引等级较高,union all通常都用于改写语句
db01 [world]> select from city where countrycode=’CHN’
union all
select from city where countrycode=’USA’;
*union 和 union all的区别
union all不对结果集做去重复处理,但是工作中union all较为常用
union 会做去重操作,因涉及到一些类似计算排序等操作,因此性能相对union all较差,所以较少使用
5.1.8 多表连接查询(内连接)
作用:单表数据不能满足查询需求时.
语法:
1、最核心的是,找到多张表之间的关联条件列
2、列书写时,必须是:表名.列
3、所有涉及到的查询列,都放在select后
4、将所有的过滤,分组,排序等条件按顺序写在on的后面
例子:
两张表 1、查询世界上小于100人的城市,所在的国家名字,国土面积,城市名,人口数
db01 [world]> select country.name,country.SurfaceArea, city.name,city.population from city join country on city.countrycode = country.code where city.population<100;
多张表 2.、A join B on A.x=B.y join C on B.m=C.n 多张表关联同两张表类似,都是要找到表于表之间的关联列
lab环境
----学生管理系统
DROP DATABASE school;
CREATE DATABASE school CHARSET utf8mb4;
USE school
CREATE TABLE school.student(
sno INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT'学号',
sname VARCHAR(20) NOT NULL COMMENT '姓名',
sage TINYINT UNSIGNED NOT NULL COMMENT '年龄',
ssex ENUM('f','m') NOT NULL DEFAULT 'm' COMMENT '性别'
)ENGINE=INNODB CHARSET=utf8mb4;
CREATE TABLE school.course(
cno INT NOT NULL PRIMARY KEY COMMENT '课程编号',
cname VARCHAR(20) NOT NULL COMMENT '课程名字',
tno INT NOT NULL COMMENT '教师编号'
)ENGINE=INNODB CHARSET utf8mb4;
CREATE TABLE school.sc (
sno INT NOT NULL COMMENT '学号',
cno INT NOT NULL COMMENT '课程编号',
score INT NOT NULL DEFAULT 0 COMMENT '成绩'
)ENGINE=INNODB CHARSET=utf8mb4;
CREATE TABLE school.teacher(
tno INT NOT NULL PRIMARY KEY COMMENT '教师编号',
tname VARCHAR(20) NOT NULL COMMENT '教师名字'
)ENGINE=INNODB CHARSET utf8mb4;
INSERT INTO student(sno,sname,sage,ssex)
VALUES (1,'zhang3',18,'m');
INSERT INTO student(sno,sname,sage,ssex)
VALUES
(2,'zhang4',18,'m'),
(3,'li4',18,'m'),
(4,'wang5',19,'f');
INSERT INTO student
VALUES
(5,'zh4',18,'m'),
(6,'zhao4',18,'m'),
(7,'ma6',19,'f');
INSERT INTO student(sname,sage,ssex)
VALUES
('oldboy',20,'m'),
('oldgirl',20,'f'),
('oldp',25,'m');
INSERT INTO teacher(tno,tname) VALUES
(101,'oldboy'),
(102,'hesw'),
(103,'oldguo');
DESC course;
INSERT INTO course(cno,cname,tno)
VALUES
(1001,'linux',101),
(1002,'python',102),
(1003,'mysql',103);
DESC sc;
INSERT INTO sc(sno,cno,score)
VALUES
(1,1001,80),
(1,1002,59),
(2,1002,90),
(2,1003,100),
(3,1001,99),
(3,1003,40),
(4,1001,79),
(4,1002,61),
(4,1003,99),
(5,1003,40),
(6,1001,89),
(6,1003,77),
(7,1001,67),
(7,1003,82),
(8,1001,70),
(9,1003,80),
(10,1003,96);
SELECT * FROM student;
SELECT * FROM teacher;
SELECT * FROM course;
SELECT * FROM sc;
表结构:
练习例子:
1、统计zhang3,学习了几门课
db01 [world]> SELECT student.sname,COUNT(sc.cno) FROM student JOIN sc ON student.sno=sc.sno WHERE student.sname=’zhang3’;
2、查询zhang3,学习的课程名称有哪些?
db01 [world]> SELECT student.sname,course.cname FROM student JOIN sc ON student.sno=sc.sno JOIN course ON sc.cno=course.cno WHERE student.sname=’zhang3’ GROUP BY student.sname;
3、查询oldguo老师教的学生名和个数
db01 [world]>select teacher.tname,group_concat(student.sname),count(student.sname) from student join sc on student.sno=sc.sno join course on sc.cno=course.cno join teacher on course.tno=teacher.tno group by teacher.tname;
4、查询oldguo所教课程的平均分数
db01 [world]>SELECT teacher.tname,AVG(sc.score)FROM teacher JOIN course ON teacher.tno=course.tno JOIN sc ON course.cno=sc.cno WHERE teacher.tname=’oldguo’ GROUP BY sc.cno;
5、每位老师所教课程的平均分,并按平均分排序
db01 [world]> SELECT teacher.tname,course.cname,AVG(sc.score) FROM teacher JOIN course ON teacher.tno=course.tno JOIN sc ON course.cno=sc.cno GROUP BY teacher.tname,course.cno ORDER BY AVG(sc.score);
6、查询oldguo所教的不及格的学生姓名
SELECT teacher.tname,student.sname,sc.score
FROM teacher
JOIN course
ON teacher.tno
=course.tno
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
WHERE teacher.tname=’oldguo’ AND sc.score<60;
7、查询所有老师所教学生不及格的信.息
SELECT teacher.tname,GROUP_CONCAT(CONCAT(student.sname,”:”,sc.score))
FROM teacher
JOIN course
ON teacher.tno=course.tno
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
WHERE sc.score<60 GROUP BY teacher.tno;
5.1.9 别名应用
1、表别名
表别名是全局调用的
SELECT t.tname AS 讲师,GROUP_CONCAT(CONCAT(s.sname,”:”,sc.score)) AS 不及格学生及分数
FROM teacher AS t
JOIN course AS c
ON t.tno=c.tno
JOIN sc
ON c.cno=sc.cno
JOIN student AS s
ON sc.sno=s.sno
WHERE sc.score<60 GROUP BY t.tno;
2、列别名
列别名可以被having和order by调用
SELECT teacher.tname AS 讲师,GROUP_CONCAT(CONCAT(student.sname,”:”,sc.score)) AS 不及格学生及分数
FROM teacher
JOIN course
ON teacher.tno=course.tno
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
WHERE sc.score<60 GROUP BY teacher.tno;
5.2 DQL之show
show databases; 查看所有数据库名称
show tables; 查看表名
show create databases xx 查看建库语句
show create table xx 查看建表语句
show processlist 查看所有用户连接情况
show charset; 查看支持的字符集
show collation; 查看所有支持的校对规则
show grants for xx; 查看用户的权限信息
show variables like "%xx%" 查看参数信息
show engines; 查看所有支持的存储引擎类型
show index from xxx 查看表的索引信息
show engine innodb status\G 查看innodb引擎详细状态信息
show binary logs 查看二进制日志的列表信息
show binlog events in ''; 查看二进制事件信息
show master status; 查看mysql当前使用二进制日志信息
show slave status\G 查看从库状态信息
show relaylog events in '' 查看中继日志的事件信息
show status like '' 查看数据库整体状态信息
注意知识点
1、关于group by的sql_mode
only_full_group_by
说明:出现这种问题直接描述就是,group by在对某个列值进行分组时,默认会去重,这种可能就会导致一个组后面会对应多个列值,因此会出现报错的情况,5.7默认开起此参数,5.6和8.0没有,会显示第一个匹配的列值
1)在5.7版本中mysql sql_mode参数中自带,5.6和8.0都没有
2)在带有group by子句的select中,select后的条件列(非主键列),要么时group by后的列,要么需要在函数中进行包裹(group_concat函数)
在5.7版本中关闭此参数
查询此参数
关闭此参数
编辑mysql的配置文件vim /etc/my.cnf
[mysqld]
user=mysql
basedir=/app/mysql
datadir=/data/mysql/instance01
socket=/tmp/mysql.sock
server_id=6
port=3306
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
[mysql]
socket=/tmp/mysql.sock
重启mysqld服务,再次查看此参数影响的结果
解释:按照正常情况,原来是2个root行,对应有两个host值,对user进行group by操作之后,root会被合并成一个,但是host还是有2行数据,因此为解决此问题,sql_mode参数会影响这总情况的显示结果,当关闭此参数时,可以显示一行数据,但是5.7版本才有此参数,5.6和8.0都没有此参数,默认就可以显示一行数据,如果想要正常显示,可以使用group_concat()函数,使其让多行在一行显示。
2、group_concat
列转行聚合函数,这个函数就是为了解决上述问题,将group by分组对应的多个列值进行聚合成单行显示
3、concat
做列值拼接
4、关于多表连接语法规则
1)首先找涉及到的所有列
2)找到表和表之间的关联列
3)关联条件写在on后面 A join B on 关联列
4)所有需要查询的信息放在select后
5)其他的过滤条件where group by having order by limit
注意:对表连接中,驱动表(第一张表)选择数据行少的表,后续所有表的关联列尽量是主键或者唯一键(表设计),至少建立一个索引
5、distinct 去重