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.查看表结构

    1. mysql> show tables;//查看该数据库有哪些表
    image.png
    1. mysql> desc dept;//查看表的结构
    image.png
  1. mysql> select * from dept;//查看部门表中的数据

image.png

4.常用命令

mysql> select databases; 查看当前使用的是哪个数据库
mysql> select version(); 查看mysql的版本号
\C 命令结束一条语句
exit 退出mysql

四、SQL语句

1.简单的查询语句(DQL)

1.1 语法格式

  1. select 字段名1,字段名2... from 表名;

注:

  • 任何一条sql语句以“;” 结尾;
  • sql语句不区分大小写。
  • 查询所有字段可用*通配符,但是效率很低,在实际开发中不要使用。

    1.2 字段可以参与数学运算

    查询员工年薪:

    1. select ename,sal*12 from emp;

    image.png
    注:所有的数据库规定,只要NULL参与运算,不管进行何种运算,结果都是NULL。

    1.3 给查看结果的列重命名

    1. select ename,sal*12 as yearsal from emp;

    image.png
    中文别名:

    1. select ename,sal*12 as '年薪' from emp;
    2. select ename,sal*12 '年薪' from emp;

    注意:

  • 标准sql语句中要求字符串使用单引号,虽然mysql支持双引号,尽量别用,因为其他数据库不支持。

  • as 可以省略。

image.png

2.条件查询

2.1 语法格式

  1. select
  2. 字段,字段...
  3. from
  4. 表名
  5. where
  6. 条件;

执行顺序:先from,然后where,最后select。
image.png

2.2 示例

查询员工工资等于5000的姓名?

  1. select ename from emp where sal=5000;

查询SMITH的工资?

  1. select sal from emp where ename='SMITH'

找出工资高于3000的员工?

  1. select ename,sal from emp where sal>3000;

找出工资不等于3000的?

  1. select ename,sal from emp where <> 3000;
  2. select ename,sal from emp where != 3000;

2.3 between … and …

找出工资在1100和3000的员工,包括1100和3000?

  1. select ename,sal from emp where sal >=1100 and sal<=3000;
  2. select ename,sal from emp where sal between 1100 and 3000 //between...and...是闭区间

注意:between …and…左小右大,between and 除了可以使用在数字方面之外,还可以使用在字符串方面。

  1. select ename from emp where ename between 'A' and 'C';//字符左闭右开

2.4 is null和is not null

找出哪些人津贴为null?

  1. select ename,sal,comm from emp where comm is null;

image.png
找出哪些人津贴不为null?

  1. select ename,sal,comm from emp where comm is not null;

注:在数据库中,NULL不是一个值,代表什么也没有,为空,不能用0来衡量。
找出哪些人津贴为0?

  1. select ename,sal,comm from emp where comm is null or comm = 0;

image.png

2.5 and和or的优先级问题

找出薪资大于1000并且部门编号为20或30的员工?

  1. select ename,sal,deptno from emp where sal>1000 and deptno=20 or deptno=30;//错误

image.png

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

image.png
注:遇到and和or联合使用的情况,优先级不确定的时候用小括号。

2.6 条件查询in

in等同于or,找出工作岗位是manager和salesman的员工?

  1. select ename,job from emp where job='manager' or job='salesman';
  2. select ename,job from emp where job in ('manager','salesman');

找出工资是800和1000的员工?

  1. select ename,sal from emp where sal in (800,1000);

找出工资不是800和1000的员工?

  1. select ename,sal from emp where sal not in (800,1000);

2.7 模糊查询like

在模糊查询中,有两个特殊的符号,%和。其中%代表任意多个字符,代表任意一个字符。
找出名字当中有o的员工?

  1. select ename from emp where ename like '%o%';

找出第二个字母是a的员工?

  1. select ename from emp where ename like '_a%';

注:假设一个string表中的value字段全是字符串,如何从中找出带或%的记录?使用转义字符,让无特殊含义。

  1. select value from string where value like '%_%';//错误,全部字符串都符合要求
  2. select value from string where value like '%\_%';

3.数据排序(升序、降序)

按照工资升序排序?

  1. select
  2. ename,sal
  3. from
  4. emp
  5. order by
  6. sal;

注意:默认是升序,怎么指定升序或者降序?asc表示指定升序,desc 表示降序。

  1. select ename,sal from emp order by sal;//默认升序
  2. select ename,sal from emp order by sal asc;//升序
  3. select ename,sal from emp order by sal desc;//降序

按照工资的降序排列,当工资相同的时候再按照名字的升序排列。

  1. select ename,sal from emp order by sal desc,ename asc;

注意:越靠前的字段越能起到主导作用,只有当前面的字段无法完成排序的时候,才会用到后面的字段。
找出工作岗位是SALESMAN的员工,并且要求按照薪资的降序排列。

  1. select
  2. ename,job,sal
  3. from
  4. emp
  5. where
  6. job='SALEMAN'
  7. order by
  8. sal 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这种情况。
示例:计算津贴总和

  1. select sum(comm) from emp where comm is not null;//不需要额外加条件,自动忽略null
  2. select sum(comm) from emp;

4.3 分组函数使用示例

算出所有员工薪资总和:

  1. select sum(sal) from emp;

image.png
算出所有员工的平均工资:

  1. select avg(sal) from emp;

image.png
计算员工总人数:

  1. select count(*) from emp;//14
  2. select count(ename) from emp;//14

image.png
分组函数也能组合起来使用:

  1. select count(*),sum(sal),avg(sal),max(sal) from emp;

image.png
找出工资高于平均工资的员工:

  1. 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是对分组之后的数据进行再次过滤。

示例:找出每个工作岗位的最高薪资。

  1. select max(sal),job from emp group by job;

image.png
注:分组函数一般都会和group by 联合使用,这也是为什么它被称为分组函数的原因。并且任何一个分组函数都是在group by语句结束之后才会执行的。当一条sql语句没有group by的话,整张表的数据会自成一组。

  1. select ename ,max(sal) ,job from emp group by job;

以上语句在mysql中,查询结果是有的,但是结果没有意义,在oracle数据库当中会报错,语法错误。oracle的语法规则比mysql语法规则严谨。
记住一个规则:当一条语句中有group by 的话,select 后面只能跟分组函数和参与分组的字段。

5.2 为什么where子句中不能使用分组函数?

找出工资高于平均工资的员工:

  1. select ename,sal from emp where sal > avg(sal);//Invalid use of group function
  1. select 5
  2. ...
  3. from 1
  4. ...
  5. where 2
  6. ...
  7. group by 3
  8. ...
  9. having 4
  10. ...
  11. order by 6
  12. ..

执行顺序 where>group by>分组函数,只有分组后才能使用分组函数,如果在where子句中使用分组函数,此时还没分组。
找出工资高于平均工资的员工?
第一步:

  1. select avg(sal) from emp;

image.png
第二步:

  1. select ename,sal from emp where sal>2073.214286;

image.png
合并:

  1. select ename,sal from emp where sal>(select avg(sal) from emp);//子查询

image.png
每个工作岗位的平均薪资?

  1. select job,avg(sal) from emp group by job;

image.png

5.3 多字段分组查询(联合分组)

示例:找出每个部门不同工作岗位的最高薪资
image.png

  1. select deptno,job,max(sal) from emp group by deptno,job;

image.png

5.4 having和where的选择

wherehaving之后都是筛选条件,但是有区别的:

  • where在group by前, having在group by 之后
  • 聚合函数(avg、sum、max、min、count),不能作为条件放在where之后,但可以放在having之后

示例1:找出每个部门的最高薪资,要求显示薪资大于2500的数据。

  • 第一步:找出每个部门的最高薪资

    1. select max(sal),deptno from emp group by deptno;

    image.png

  • 第二步:找出薪资大于2900

    1. select max(sal) ,deptno from emp group by deptno having max(sal)>2900; //这种方式效率低
    2. select max(sal) ,deptno from emp where sal >2900 group by deptno;//效率较高

    image.png
    为什么第一种方式效率低?
    因为它是把所有数据都分组后计算出最高薪资,再把低于2900的排除。而第二种方式在一开始就把薪资低于2900的排除,不参与分组和计算。所以,建议能使用where过滤的使用where。
    示例2:找出每个部门的平均薪资,要求显示薪资大于2000的数据

  • 第一步:找出每个部门的平均薪资

    1. select deptno,avg(sal) from emp group by deptno;
  • 第二步:要求显示薪资大于2000的数据

    1. 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 …

  1. 语句顺序不能颠倒,但是可以省略。
  2. <a name="fwbKY"></a>
  3. ## 6.查询结果去重
  4. distinct关键字用来去除重复记录,只能出现在所有字段最前面。
  5. <a name="gn3lU"></a>
  6. ### 6.1 单字段去重
  7. ```sql
  8. select distinct job from emp;
  9. //表示工作岗位的种类

image.png

  1. select count(distinct job) from emp;//统计岗位种类数量

image.png

6.2 多字段联合去重

  1. select distinct deptno,job from emp;
  2. //表示不同部门不同的岗位

image.png

6.3 错误示例

  1. select deptno,distinct job from emp;//错误

distinct关键字只能出现在所有字段最前面。

6.4 DISTINCT关键字总结

使用 DISTINCT 关键字时需要注意以下几点:

  • DISTINCT 关键字只能在 SELECT 语句中使用。
  • 在对一个或多个字段去重时,DISTINCT 关键字必须在所有字段的最前面。
  • 如果 DISTINCT 关键字后有多个字段,则会对多个字段进行组合去重,也就是说,只有多个字段组合起来完全是一样的情况下才会被去重。