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语句的应用

create、drop、alter

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));
image.png
NOT NULL:非空约束,必填项,不允许为空值
UNIQUE KEY:唯一键约束,不允许重复值
DEFAULT:一般配合NOT NULL一起使用
UNSIGNED:无符号,一般是配合数字列,非负数
COMMENT:注释
AUTO_INCREMENT:自增长的列

2.2.2 表定义

1)在zabbix下创建一张stu的表

  1. CREATE TABLE zabbix.stu(
  2. id INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '学号',
  3. sname VARCHAR(255) NOT NULL COMMENT '姓名',
  4. age TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '年龄',
  5. gender ENUM('m','f','n') NOT NULL DEFAULT 'n' COMMENT "性别",
  6. intime DATETIME NOT NULL DEFAULT NOW() COMMENT '入学时间'
  7. )ENGINE INNODB CHARSET utf8mb4;
  8. 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语句的应用

insert、update、delete

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;

  1. mysql> select * from stu;
  2. +----+-------+-----+--------+---------------------+
  3. | id | sname | age | gender | intime |
  4. +----+-------+-----+--------+---------------------+
  5. | 1 | xiang | 25 | m | 2022-01-21 16:33:07 |
  6. | 2 | shi | 19 | m | 2022-01-21 16:34:27 |
  7. | 3 | chuan | 20 | m | 2022-01-21 16:37:10 |
  8. | 4 | aaa | 11 | f | 2022-01-21 16:38:30 |
  9. | 5 | bbb | 12 | m | 2022-01-21 16:38:30 |
  10. | 6 | cccc | 16 | m | 2022-01-21 16:38:30 |
  11. +----+-------+-----+--------+---------------------+
  12. 6 rows in set (0.00 sec)
  13. mysql> update stu set sname="zhangshan",age=18 where id=4;
  14. Query OK, 1 row affected (0.01 sec)
  15. Rows matched: 1 Changed: 1 Warnings: 0
  16. mysql> select * from stu;
  17. +----+-----------+-----+--------+---------------------+
  18. | id | sname | age | gender | intime |
  19. +----+-----------+-----+--------+---------------------+
  20. | 1 | xiang | 25 | m | 2022-01-21 16:33:07 |
  21. | 2 | shi | 19 | m | 2022-01-21 16:34:27 |
  22. | 3 | chuan | 20 | m | 2022-01-21 16:37:10 |
  23. | 4 | zhangshan | 18 | f | 2022-01-21 16:38:30 |
  24. | 5 | bbb | 12 | m | 2022-01-21 16:38:30 |
  25. | 6 | cccc | 16 | m | 2022-01-21 16:38:30 |
  26. +----+-----------+-----+--------+---------------------+
  27. 6 rows in set (0.00 sec)

4.3 DML之delete

删除某行数据
mysql> delete from stu where id=6 ;

5DQL语句的应用

select、show

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表结构
image.png
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;
image.png
7、组合拼接显示
CONCAT
db01 [world]> SELECT CONCAT(district,”:”,GROUP_CONCAT(NAME)) FROM city WHERE countrycode=’CHN’ GROUP BY District;
image.png

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环境

  1. ----学生管理系统
  2. DROP DATABASE school;
  3. CREATE DATABASE school CHARSET utf8mb4;
  4. USE school
  5. CREATE TABLE school.student(
  6. sno INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT'学号',
  7. sname VARCHAR(20) NOT NULL COMMENT '姓名',
  8. sage TINYINT UNSIGNED NOT NULL COMMENT '年龄',
  9. ssex ENUM('f','m') NOT NULL DEFAULT 'm' COMMENT '性别'
  10. )ENGINE=INNODB CHARSET=utf8mb4;
  11. CREATE TABLE school.course(
  12. cno INT NOT NULL PRIMARY KEY COMMENT '课程编号',
  13. cname VARCHAR(20) NOT NULL COMMENT '课程名字',
  14. tno INT NOT NULL COMMENT '教师编号'
  15. )ENGINE=INNODB CHARSET utf8mb4;
  16. CREATE TABLE school.sc (
  17. sno INT NOT NULL COMMENT '学号',
  18. cno INT NOT NULL COMMENT '课程编号',
  19. score INT NOT NULL DEFAULT 0 COMMENT '成绩'
  20. )ENGINE=INNODB CHARSET=utf8mb4;
  21. CREATE TABLE school.teacher(
  22. tno INT NOT NULL PRIMARY KEY COMMENT '教师编号',
  23. tname VARCHAR(20) NOT NULL COMMENT '教师名字'
  24. )ENGINE=INNODB CHARSET utf8mb4;
  25. INSERT INTO student(sno,sname,sage,ssex)
  26. VALUES (1,'zhang3',18,'m');
  27. INSERT INTO student(sno,sname,sage,ssex)
  28. VALUES
  29. (2,'zhang4',18,'m'),
  30. (3,'li4',18,'m'),
  31. (4,'wang5',19,'f');
  32. INSERT INTO student
  33. VALUES
  34. (5,'zh4',18,'m'),
  35. (6,'zhao4',18,'m'),
  36. (7,'ma6',19,'f');
  37. INSERT INTO student(sname,sage,ssex)
  38. VALUES
  39. ('oldboy',20,'m'),
  40. ('oldgirl',20,'f'),
  41. ('oldp',25,'m');
  42. INSERT INTO teacher(tno,tname) VALUES
  43. (101,'oldboy'),
  44. (102,'hesw'),
  45. (103,'oldguo');
  46. DESC course;
  47. INSERT INTO course(cno,cname,tno)
  48. VALUES
  49. (1001,'linux',101),
  50. (1002,'python',102),
  51. (1003,'mysql',103);
  52. DESC sc;
  53. INSERT INTO sc(sno,cno,score)
  54. VALUES
  55. (1,1001,80),
  56. (1,1002,59),
  57. (2,1002,90),
  58. (2,1003,100),
  59. (3,1001,99),
  60. (3,1003,40),
  61. (4,1001,79),
  62. (4,1002,61),
  63. (4,1003,99),
  64. (5,1003,40),
  65. (6,1001,89),
  66. (6,1003,77),
  67. (7,1001,67),
  68. (7,1003,82),
  69. (8,1001,70),
  70. (9,1003,80),
  71. (10,1003,96);
  72. SELECT * FROM student;
  73. SELECT * FROM teacher;
  74. SELECT * FROM course;
  75. SELECT * FROM sc;

表结构:
image.png
练习例子:
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

  1. show databases; 查看所有数据库名称
  2. show tables; 查看表名
  3. show create databases xx 查看建库语句
  4. show create table xx 查看建表语句
  5. show processlist 查看所有用户连接情况
  6. show charset; 查看支持的字符集
  7. show collation; 查看所有支持的校对规则
  8. show grants for xx; 查看用户的权限信息
  9. show variables like "%xx%" 查看参数信息
  10. show engines; 查看所有支持的存储引擎类型
  11. show index from xxx 查看表的索引信息
  12. show engine innodb status\G 查看innodb引擎详细状态信息
  13. show binary logs 查看二进制日志的列表信息
  14. show binlog events in ''; 查看二进制事件信息
  15. show master status; 查看mysql当前使用二进制日志信息
  16. show slave status\G 查看从库状态信息
  17. show relaylog events in '' 查看中继日志的事件信息
  18. show status like '' 查看数据库整体状态信息

注意知识点

1、关于group by的sql_mode
only_full_group_by
image.png
说明:出现这种问题直接描述就是,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版本中关闭此参数
查询此参数
image.png
关闭此参数
编辑mysql的配置文件vim /etc/my.cnf

  1. [mysqld]
  2. user=mysql
  3. basedir=/app/mysql
  4. datadir=/data/mysql/instance01
  5. socket=/tmp/mysql.sock
  6. server_id=6
  7. port=3306
  8. sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
  9. [mysql]
  10. socket=/tmp/mysql.sock

重启mysqld服务,再次查看此参数影响的结果
image.png
image.png
解释:按照正常情况,原来是2个root行,对应有两个host值,对user进行group by操作之后,root会被合并成一个,但是host还是有2行数据,因此为解决此问题,sql_mode参数会影响这总情况的显示结果,当关闭此参数时,可以显示一行数据,但是5.7版本才有此参数,5.6和8.0都没有此参数,默认就可以显示一行数据,如果想要正常显示,可以使用group_concat()函数,使其让多行在一行显示。
2、group_concat
列转行聚合函数,这个函数就是为了解决上述问题,将group by分组对应的多个列值进行聚合成单行显示
image.png
3、concat
做列值拼接
image.png
4、关于多表连接语法规则
1)首先找涉及到的所有列
2)找到表和表之间的关联列
3)关联条件写在on后面 A join B on 关联列
4)所有需要查询的信息放在select后
5)其他的过滤条件where group by having order by limit
注意:对表连接中,驱动表(第一张表)选择数据行少的表,后续所有表的关联列尽量是主键或者唯一键(表设计),至少建立一个索引
5、distinct 去重
image.png