MySQL学习
数据库: DateBase,简称DB,是存储数据的仓库
数据库管理系统: DateBaseManagement,简称DBMS,专门用于管理数据库中的数据,可以对数据库进行增删改查
常见数据库管理系统: MySQL, Oracle, MS SqlServer, DB2等
SQL: 结构化查询语句
三者关系: DBMS >> 执行 >> SQL >> 操作 >> DB
在windows操作系统当中,启动服务 net start 服务名 关闭服务 net stop 服务名
连接mysql及简单查看
本地连接mysql数据库服务器方式 mysql -uroot -p 退出 exit
查看mysql中有哪些数据库 show databases;
使用某个数据库 use 数据库名;
创建数据库 create database 数据库名称;
表的理解
表(table)是数据库的基本单位(直观),在数据库中用表的形式来表示数据
任何一张又有行列,行(row):被称为数据/记录 列(cloumn):被称为字段
每一个子段都有:字段名,数据类型,约束等属性
约束:约束有很多,其中有一个叫做唯一性约束,这种约束添加后,该字段中不可再重复
查看数据库下的表 show tables;
SQL语句的分类
DQL 数据查询语言(带select关键字)
DML ** 数据操作语言(对数据**增删改查操作insert,delete,update)
DDL 数据定义语言(对表的结构进行操作create,alter,drop)
TCL 事务控制语言(commit,rollback)
DCL 数据控制语言(grant,revoke)
导入数据并查看表
- 找到数据路径(路径中不能有中文)
- 进入指定数据库 并source 路径
查看表 show tables;
查看表中数据 select * from 表名;
查看表结构 desc 表名;
SQL常用语句
不见分号不执行
查看数据库版本号 select version();
查看当前数据库 select datebase();
终止输入 \c
DQL语句
查询一个字段 select 字段名 from 表名;
查询多个字段 select 字段名,字段名 from 表名
查询所有字段 select * from dept (实践开发不太建议,效率低,可读性差)
给查询的列取别名 select 字段名 as 别名 from 表名 (只是显示,不进行更改) as可以省略
取别名带空格或者为中文怎么处理? 用单引号或者双引号 将别名括起来 例如:select dname ‘dept name’ from dept;
在select查询时 字段可以数学表达式
条件查询
语法 select 字段1,字段2,字段3 from 表名 where 条件
字段处为’字面量/字段值’ 效果为
select 'abc' as name from emp;
结果为
+------+
| name |
+------+
| abc |
| abc |
| abc |
| abc |
+------+
条件有
= 等于
<>或者!= 不等于 大于小于...
berween...and...两个值之间,左小右大,闭区间 等同于>= <=
is null 为 null (is not null不为空)
and 并且 or或者
in 包含 相当于多个or(not in不在这个范围中)
not not可以取非 主要在用在 is 或者 in 中
like like 模糊查询 支持%或下划线匹配
%匹配任意个字符
下划线,一个下划线只匹配一个字符
练习 1.select empno,ename from emp where sal = 800;
2.select empno,ename,sal, from emp where ename = 'Tom';
3.select empno,ename from emp where sal b 800;
4.select empno,ename from emp where sal >=2450 and sal <=3000;
5.select empno,ename,sal from emp where sal between 2450 and 3000;
6.select empno,ename,sal,comm from emp where comm is not null;
7.select empno,ename,job from emp where job = 'manager' and sal <= 3000;
8.select empno,ename,job from emp where job = 'manager' or job = 'salesman';
9.select empno,ename,job from emp where job in ('manager' , 'salesman';)
10.select empno,ename,job,sal from emp where sal not in (1000,2500);
11.select empno,ename from emp where ename like '%O%';里面含O
12.select empno,ename from emp where ename like '%T';结尾为T
13.select empno,ename from emp where ename like '__R%';第三位为T
14.select empno,ename from emp where ename like '%/_%';里面含_ /转义
注意 1.and 优先级高于 or,为了便于查询可以加括号提高优先级
2.null不可以用等号衡量,他不是一个值
3.in不是一个区间,是具体值
4.%任意多个 _任意一个
排序查询
排序查询(默认升序) order by xxx
指定降序排序 order by xxx desc
指定升序排序 order by xxx asc
多字段排序 order by xxx desc(asc),xxx desc(asc) (条件1相同在根据条件2排序)
根据查询结构的位置进行排序 order bt 数字
关键字顺序: select … from … where … order by …
!!!执行顺序 1.from 2.where 3.select 4.order by
单行处理函数
特点:一个输入对于一个输出
lower() 转换小写
upper() 转化大写
substr 取子串(substr(被截取的字符串起始下标,截取长度)) select substr(ename, 1, 1)
实践
查询员工名字第一个字是A的员工信息
1.select ename from emp where ename like '%A';
2.select ename from emp where substr(ename,1,1) = 'A';
concat 字符串拼接 concat(xxx,xxx)
实践
学生首字母大写查询
select concat(upper(substr(name,1,1),substr(name,2,length(name)-1)) as result from t_student;
length() 取长度
trim() 去空格
round(数字,保留几位小数) 四舍五入
rand() * 多少以内 生成随机数
ifnull(xxx,xxx) 空处理函数
在数据库中有null参与 结果都为null;ifnull则是为了避免这种情况;
select ename,(sal + ifnull(comm,0)* 12) as salcomm from emp;
case … when … then … when … then … else … end 当什么时候干什么
select ename,job,(case job when 'MANAGER' then sal * 1.1 when 'SALESMAN' then sal * 1.5 else sal end) as newsal from emp;
多行处理函数/分组函数
特点:多个输入对于一个输出,必须先分组在进行使用,如果没有进行分组,则全表为一组,也叫分组函数
count() 计数 sum() 求和 **avg()**平均值 max() 最大值 min() 最小值
分组函数自动忽略NULL
1.count(具体字段):表示统计该字段下所有不为NULL的元素总和
count(*):统计行数
2.分组函数不可以直接用在where子句中 ???在分组查询里解答
3.分组函数可以一起用
分组查询
实际应用中先进行分组,再对每一组数据进行操作
select … from … group by … 分组查询
关键字组合
select ... from ... where ... group ... order by ...
执行顺序
from >> where >> group by >> select >> order by
分组函数不可以直接用在where后面的原因
select ename,sal from emp where sal > min(sal); //报错
先分组在用分组函数
where执行时还未进行分组,所以where后面不能出现分组函数,在select后面用分组函数则是已经分组过了
实例
找出每个工作岗位的工资和
select job,sum(sal) from emp group by job;
执行顺序 先在emp中查询数据 >> 根据job字段进行分组 >> 然后继续sum(sal);
如果语句改为 select ename,job,sum(sal) from emp group by job;
ename 无法被分组显示,因为分组的数量不同,只可以查询出第一个名字,oracle语法中会报错;
在一条select语句中,如果有group by,select后面只可以跟参加分组的字段,以及分组函数
找出每个部门,不同工作岗位的最高薪资
select deptno,job,sum(sal) from emp group by deptno,job;
having 可对分组后数据继续过滤,但必须和group by 一起使用
having执行顺序再group by之后
显示每个部门最高薪资且薪资大于3000的:
1. select deptno,max(sal) from emp where sal > 3000 group by deptno;
2. select deptno,max(sal) from emp group by deptno having max(sal) > 3000;
2 语句效率低于 1,所以where和having 优先使用where,实在无法完成再使用having
无法使用where的情况(对分组后的数据继续再次处理的情况) 因为where后面不可以用分组函数,执行顺序原因
select deptno,avg(sal) from emp group by deptno having avg(sal) > 2500;
练习 找出每个岗位的平均薪资,要求显示平均薪资大于1500的,除MANAGER之外,要求按照平均薪资降序排列
select job,avg(sal) as avgsal from emp where job != 'MANAGER' group by job having avg(sal) > 1500 order by avgsal desc;
distinct 把查询结果去除重复记录,只能放在所有字段前面,可用分组函数
select distinct job from emp;
select ename,distinct job from emp; //错误
select distinct job,deptno from emp; //表联合起来去除重新记录
连接查询
几个表联合起来查询数据
年代分类:SQL92 SQL99
表连接方式分类 | |
---|---|
内连接 | 等值连接,非等值连接,自连接 |
外连接 | 左外连接,右外连接 |
全连接 | ----- |
两个表连续查询 无限制条件 >>> 笛卡尔积现象 >> 连接次数越多,效率越低
避免笛卡尔积现象,匹配次数没有减少 >> 加入where条件
举例 select ename,dname from emp,dept where emp.deptno = dept.deptno;
效率提高 > 起别名
举例 select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;
//92语法
内连接之等值查询
例 查询每个员工所在部门的部门名称,显示员工名和部门名;
SQL92语法 select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno and ...;
缺点 :结构不清晰,后续筛选继续放在where后面
SQL99语法 select e.ename,d.dname from emp e inner join dept d on e.deptno = d.deptno where 筛选条件;
优点 :表连接条件独立,连接以后,进一步筛选,再继续加where
内连接之非等值查询
例 找出每个员工的薪资等级,要求显示员工名,薪资,薪资等级;
select e.ename,e.sal,s.grade from emp e inner join salgrade s on e.sal >= s.losal and e.sal <= s.hisal;
内连接之自连接
例 查询员工上级领导,要求显示员工名和对应领导名;
select a.ename as '员工名',b.ename as '领导名' from emp a inner join emp b on a.mgr = b.empno;
自连接技巧:一张表当做两张表
外连接
例 查询员工上级领导,要求显示员工名和对应领导名,无领导也显示;
在join前加right或者left,将一侧的全部查询,捎带关键查询另一侧表,right为右外连接,left为左外连接;
右外连接 select e.ename,d.dname from emp e right outer join dept d on e.deptno = d.deptno;
内外连接区别
内连接:AB两个表没有主次,完全能够匹配到条件才查询出来
外连接:分主从关系,join前提示的为主表
外连接的查询结果条数一定是大于内连接的查询结果条数的
案例查询每个员工的上级领导,要求显示所有员工的名字和领导名
select a.empno as '序号', a.ename as '员工名',b.ename as '领导名' from emp a left outer join emp b on a.mgr = b.empno
多表连接
语法
select ... from a join b on a和b的连接条件
join c on a和c的连接条件
join d on a和d的连接条件;
内外连接都可以出现,混合使用
例 找出每个员工的部门名称以及工资等级,要求显示员工名,部门名,薪资,薪资等级,以及上级领导;
select a.ename,b.dname,a.sal,c.grade,d.empno as '领导' from emp a join dept b on a.deptno = b.deptno join salgrade c on a.sal between c.losal and c.hisal left join emp d on a.mgr = d.empno;
子查询
select语句中嵌套select语句,被嵌套的语句叫子查询
语法 select ...(select)from ...(select)where ...(select)
where子句里的子查询
例 找出比最低工资高的员工的员工姓名和工资
实现思路 第一步 查询最低工资为多少 select min(sal) from emp
第二步 找出大于800的 select ename,sal from emp where sal > 800;
第三步 合并 select ename,sal from emp where sal > (select min(sal) from emp);
from子句里的子查询
技巧 from后面的子查询可以将子查询的结构当做一张临时表;
例 找出每个岗位的平均工资的薪资等级;
第一步 找出每个岗位的平均工资 select job,avg(sal) from emp group by job;
第二步 把以上查询结果当做表t,salgrade 看做 表s,将t和s连接
条件 t表avg(sal) between s.losal and s.hisal
select t.*,s.grade from t join salgrade s on t.avg(sal) between s.losal and s.hisal
第三步 合并 select t.*,s.grade from (select job,avg(sal) asal from emp group by job) t join salgrade s on t.asal between s.losal and s.hisal
select子句里的子查询
了解即可
例 找出每个员工的部门名称,要求显示员工名,部门名?
select e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname from emp e;
select 后面的子查询只可以返回一条结果
union
例 查询工作岗位是MANAGER和SALESMAN的员工
select ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';
select ename,job from emp where job in('MANAGER','SALESMAN') ;
union的使用则为
select ename,job from emp where job = 'MANAGER'
unoin
select ename,job from emp where job = 'SALESMAN';
union的效率要高一点,对于表连接来说,每连接一次新表,则匹配次数满足笛卡尔积现象,成倍的翻,但是union可以就减少匹配的次数,在减少匹配次数的情况下,还可以完成两个结果的拼接;
union把乘法变成了加法
注意union在进行合并时,要求两个结果的集的列数相同,最好保证列和列的数据类型也要一致
limit(重要)
limit startIndex, length startlndex为起始下标(默认0),length为长度
limit在order by后面执行
将表的一部分拿出,通常在分页查询中使用,为了提高用户的体验,一次查询全部的体验差
例 按照薪资降序,取出排名在前5名的员工
select ename,sal from emp order by sal desc limit 5;
例 按照薪资降序,取出排名在3-5名的员工
select ename,sal from emp order by sal desc limit 2,3;
例 按照薪资降序,取出排名在5-9名的员工
select ename,sal from emp order by sal desc limit 4,5;
分页
每页显示pageSize条记录 第pageNo页 limit (pageNo-1)*pageSize, pageSize
DQL语句总结
select … from … where … group by … having … order by … limit …
执行顺序 1.from 2.where 3.group by 4.having 5.select 6.order by 7.limit
DDL语句
表的创建
语法格式
create table 表名(
)