B站链接:MySQL基础入门到精通视频教程-MySQL数据库实战(内含MySQL34道面试题)
一、数据库安装卸载
https://blog.csdn.net/qq_43648337/article/details/112151639?spm=1001.2014.3001.5501
二、数据库概述
1.DB DBMS SQL的关系
DB:DataBase,数据库,实际在硬盘上以文件的形式存在。
DBMS:数据库管理系统,常见的有MySQL、Oracle、DB2、Sybase、SqlServer…等。
SQL:结构化查询语言,是一门标准的通用语言,适用于所有的数据库管理系统。SQL属于高级语言,在执行的时候,实际上会先进行编译再执行,编译由数据库管理系统完成。
2.什么是表?
表:table,是数据库的基本组成单元,所有的数据都以表格的形式组织,目的是可读性强。一个表包括行和列,
行:被称为数据/记录(data)
列:被称为字段(column)
| 学号(int) | 姓名(varchar) | 年龄(int) |
|---|---|---|
| 1 | 张三 | 22 |
| 2 | 李四 | 23 |
3.SQL语句分类
- DQL(数据查询语言):查询语句,凡是select语句都是DQL。
- DML(数据操作语言):insert,delete,update,对表当中的数据进行增删改。
- DDL(数据定义语言):create,drop,alter,对表结构的增删改。
- TCL(事务控制语言):commit提交事务,rollback回滚事务。
DCL(数据控制语言):grant授权,revoke撤销权限等。
三、MySQL基础
1.导入数据
登录mysql数据库管理系统:命令行窗口,mysql -uroot -p123456
- 查看有哪些数据库:show databases;(不是SQL语句,只是MySQL命令)
- 创建属于我们自己的数据库:create database sun;(不是SQL语句,只是MySQL命令)
- 使用数据库:use sun;(不是SQL语句,只是MySQL命令)
- 查看当前数据库有哪些表:show tables;(不是SQL语句,只是MySQL命令)
- 初始化数据:source sql脚本文件绝对路径(不是SQL语句,只是MySQL命令)
2.SQL脚本的理解
当一个文件的后缀为.sql,且该文件中编写了大量的sql语句,这种文件称为sql脚本。使用source命令可以执行sql脚本,批量执行sql语句,sql脚本数据量太大时,sql脚本文件可能打不开,使用source命令完成初始化。3.查看表结构
mysql> show tables;//查看该数据库有哪些表

mysql> desc dept;//查看表的结构

mysql> select * from dept;//查看部门表中的数据
4.常用命令
mysql> select databases; 查看当前使用的是哪个数据库
mysql> select version(); 查看mysql的版本号
\C 命令结束一条语句
exit 退出mysql
四、SQL语句
1.简单的查询语句(DQL)
1.1 语法格式
select 字段名1,字段名2... from 表名;
注:
- 任何一条sql语句以“;” 结尾;
- sql语句不区分大小写。
查询所有字段可用*通配符,但是效率很低,在实际开发中不要使用。
1.2 字段可以参与数学运算
查询员工年薪:
select ename,sal*12 from emp;

注:所有的数据库规定,只要NULL参与运算,不管进行何种运算,结果都是NULL。1.3 给查看结果的列重命名
select ename,sal*12 as yearsal from emp;

中文别名:select ename,sal*12 as '年薪' from emp;select ename,sal*12 '年薪' from emp;
注意:
标准sql语句中要求字符串使用单引号,虽然mysql支持双引号,尽量别用,因为其他数据库不支持。
- as 可以省略。
2.条件查询
2.1 语法格式
select字段,字段...from表名where条件;
2.2 示例
查询员工工资等于5000的姓名?
select ename from emp where sal=5000;
查询SMITH的工资?
select sal from emp where ename='SMITH';
找出工资高于3000的员工?
select ename,sal from emp where sal>3000;
找出工资不等于3000的?
select ename,sal from emp where <> 3000;select ename,sal from emp where != 3000;
2.3 between … and …
找出工资在1100和3000的员工,包括1100和3000?
select ename,sal from emp where sal >=1100 and sal<=3000;select ename,sal from emp where sal between 1100 and 3000 //between...and...是闭区间
注意:between …and…左小右大,between and 除了可以使用在数字方面之外,还可以使用在字符串方面。
select ename from emp where ename between 'A' and 'C';//字符左闭右开
2.4 is null和is not null
找出哪些人津贴为null?
select ename,sal,comm from emp where comm is null;

找出哪些人津贴不为null?
select ename,sal,comm from emp where comm is not null;
注:在数据库中,NULL不是一个值,代表什么也没有,为空,不能用0来衡量。
找出哪些人津贴为0?
select ename,sal,comm from emp where comm is null or comm = 0;
2.5 and和or的优先级问题
找出薪资大于1000并且部门编号为20或30的员工?
select ename,sal,deptno from emp where sal>1000 and deptno=20 or deptno=30;//错误

select ename,sal,deptno from emp where sal>1000 and (deptno=20 or deptno=30);//正确

注:遇到and和or联合使用的情况,优先级不确定的时候用小括号。
2.6 条件查询in
in等同于or,找出工作岗位是manager和salesman的员工?
select ename,job from emp where job='manager' or job='salesman';select ename,job from emp where job in ('manager','salesman');
找出工资是800和1000的员工?
select ename,sal from emp where sal in (800,1000);
找出工资不是800和1000的员工?
select ename,sal from emp where sal not in (800,1000);
2.7 模糊查询like
在模糊查询中,有两个特殊的符号,%和。其中%代表任意多个字符,代表任意一个字符。
找出名字当中有o的员工?
select ename from emp where ename like '%o%';
找出第二个字母是a的员工?
select ename from emp where ename like '_a%';
注:假设一个string表中的value字段全是字符串,如何从中找出带或%的记录?使用转义字符,让无特殊含义。
select value from string where value like '%_%';//错误,全部字符串都符合要求select value from string where value like '%\_%';
3.数据排序(升序、降序)
按照工资升序排序?
selectename,salfromemporder bysal;
注意:默认是升序,怎么指定升序或者降序?asc表示指定升序,desc 表示降序。
select ename,sal from emp order by sal;//默认升序select ename,sal from emp order by sal asc;//升序select ename,sal from emp order by sal desc;//降序
按照工资的降序排列,当工资相同的时候再按照名字的升序排列。
select ename,sal from emp order by sal desc,ename asc;
注意:越靠前的字段越能起到主导作用,只有当前面的字段无法完成排序的时候,才会用到后面的字段。
找出工作岗位是SALESMAN的员工,并且要求按照薪资的降序排列。
selectename,job,salfromempwherejob='SALEMAN'order bysal desc;
执行顺序:先执行from,再执行where,查询select,最后order by排序输出。
4.分组函数
4.1 5个分组函数
- count 计数
- sum 求和
- avg 平均值
- max 最大值
- min 最小值
注:分组函数一共5个,所有的分组函数都是对“某一组”数据进行操作的。分组函数也叫多行处理函数,特点是输入多行,最终输出的结果是一行。分组函数自动忽略null。
4.2 分组函数自动忽略NULL
所有的数据库规定,只要NULL参与运算,不管进行何种运算,结果都是NULL。但是分组函数会自动忽略NULL,所以即使处理的一组数据中包含NULL,也不需考虑NULL这种情况。
示例:计算津贴总和
select sum(comm) from emp where comm is not null;//不需要额外加条件,自动忽略nullselect sum(comm) from emp;
4.3 分组函数使用示例
算出所有员工薪资总和:
select sum(sal) from emp;

算出所有员工的平均工资:
select avg(sal) from emp;

计算员工总人数:
select count(*) from emp;//14select count(ename) from emp;//14

分组函数也能组合起来使用:
select count(*),sum(sal),avg(sal),max(sal) from emp;

找出工资高于平均工资的员工:
select ename,sal from emp where sal > avg(sal);//Invalid use of group function
注:SQL语法规则中规定,分组函数不可以直接使用在where子句当中。
4.4 count(*)和count(字段)的区别
count(*):不是统计某个字段中数据的个数,而是统计总记录条数(和某个字段无关)。
count(comm):表示统计comm字段中不为NULL的数据总数量。
5.分组查询
5.1 group by 和 having
- group by:按照某个字段或者某些字段进行分组。
- having:having是对分组之后的数据进行再次过滤。
示例:找出每个工作岗位的最高薪资。
select max(sal),job from emp group by job;

注:分组函数一般都会和group by 联合使用,这也是为什么它被称为分组函数的原因。并且任何一个分组函数都是在group by语句结束之后才会执行的。当一条sql语句没有group by的话,整张表的数据会自成一组。
select ename ,max(sal) ,job from emp group by job;
以上语句在mysql中,查询结果是有的,但是结果没有意义,在oracle数据库当中会报错,语法错误。oracle的语法规则比mysql语法规则严谨。
记住一个规则:当一条语句中有group by 的话,select 后面只能跟分组函数和参与分组的字段。
5.2 为什么where子句中不能使用分组函数?
找出工资高于平均工资的员工:
select ename,sal from emp where sal > avg(sal);//Invalid use of group function
select 5...from 1...where 2...group by 3...having 4...order by 6..
执行顺序 where>group by>分组函数,只有分组后才能使用分组函数,如果在where子句中使用分组函数,此时还没分组。
找出工资高于平均工资的员工?
第一步:
select avg(sal) from emp;

第二步:
select ename,sal from emp where sal>2073.214286;

合并:
select ename,sal from emp where sal>(select avg(sal) from emp);//子查询

每个工作岗位的平均薪资?
select job,avg(sal) from emp group by job;
5.3 多字段分组查询(联合分组)
示例:找出每个部门不同工作岗位的最高薪资
select deptno,job,max(sal) from emp group by deptno,job;
5.4 having和where的选择
where和having之后都是筛选条件,但是有区别的:
- where在group by前, having在group by 之后
- 聚合函数(avg、sum、max、min、count),不能作为条件放在where之后,但可以放在having之后
示例1:找出每个部门的最高薪资,要求显示薪资大于2500的数据。
第一步:找出每个部门的最高薪资
select max(sal),deptno from emp group by deptno;

第二步:找出薪资大于2900
select max(sal) ,deptno from emp group by deptno having max(sal)>2900; //这种方式效率低select max(sal) ,deptno from emp where sal >2900 group by deptno;//效率较高

为什么第一种方式效率低?
因为它是把所有数据都分组后计算出最高薪资,再把低于2900的排除。而第二种方式在一开始就把薪资低于2900的排除,不参与分组和计算。所以,建议能使用where过滤的使用where。
示例2:找出每个部门的平均薪资,要求显示薪资大于2000的数据第一步:找出每个部门的平均薪资
select deptno,avg(sal) from emp group by deptno;
第二步:要求显示薪资大于2000的数据
select deptno ,avg(sal) from emp group by deptno having avg(sal)>2000;
这种情况下,无法使用where过滤,只能使用having,因为过滤条件是在分组之后计算出来的,无法在分组之前使用where过滤。
5.5 总结DQL语句的执行顺序
```sql Select 5 … From 1 … where 2 … group by 3 … having 4 … order by 6 …
语句顺序不能颠倒,但是可以省略。<a name="fwbKY"></a>## 6.查询结果去重distinct关键字用来去除重复记录,只能出现在所有字段最前面。<a name="gn3lU"></a>### 6.1 单字段去重```sqlselect distinct job from emp;//表示工作岗位的种类

select count(distinct job) from emp;//统计岗位种类数量
6.2 多字段联合去重
select distinct deptno,job from emp;//表示不同部门不同的岗位
6.3 错误示例
select deptno,distinct job from emp;//错误
6.4 DISTINCT关键字总结
使用 DISTINCT 关键字时需要注意以下几点:
- DISTINCT 关键字只能在 SELECT 语句中使用。
- 在对一个或多个字段去重时,DISTINCT 关键字必须在所有字段的最前面。
- 如果 DISTINCT 关键字后有多个字段,则会对多个字段进行组合去重,也就是说,只有多个字段组合起来完全是一样的情况下才会被去重。
