数据库 表格是结构化文件 分行/列/主键 列叫做字段column 数据类型 名称 长度 约束
mysql -V 或者--version或者select version
DQL 数据查询语言 select
DML 数据操纵语言 insert delete update
DDL 数据定义语言 create drop alter
TCL 事物控制语言 commit rollback
DCL 数据控制语言 grant revoke
sql语句不区分大小写,以分号;结尾
show databases;
use databasename;
show tables;
desc tablename;查看这张表表结构
查看当前数据库select database()
退出ctrlC exit quit
show tables from databasename;
show create table tablename;
简单的查询
select ename from emp;
多字段查询,逗号隔开,全部的话* 别人读你程序的话可读性差效率低不建议写到java中
select ename,enum from emp;
select enpno,ename,sal*12 as yearsal from emp;
底层不会修改表中的数据只是查询出来。as关键字可省略不写。重命名中文需要加单引号
条件查询
运算符
= 等于
<> != 不等于
< <= 小于 小于等于
> >= 大于 大于等于
between and 两个值之间等同于>= and <=
is null 为 null is not null 不为空
and 并且
or 或者
in包含
not 取非 主要用在is 或 in 中
like 模糊查询 支持%或下划线匹配 %匹配任意个字符 一个下划线只匹配一个字符
查询工资=5000的
select empno,ename,sal
from emp
where sal=5000
between and 不止数字上面还可以字母 ‘A’and‘K’前闭后开
NULL代表什么也没有和0存在区别
where conn is null/is not null
and和or同时出现的话 and优先级高 要注意优先级
比如找出工资大于1800的员工 要求部门编号是20或者30的
select empno,ename,sal,deptno from emp where sal>1800 and (deptno=20 or deptno=30 )
in/not in的用法
where job=‘manager’ or job=‘salesman’
可以换成where job in(‘manager’,‘salesman’)
like用法
select ename from emp where ename like ‘%o%’;模糊查询下划线可以占一个
第二个字母是a的 like ‘_A%’
排序 order by
select ename,sal from emp order by sal desc,ename asc;以前面的条件为主,后面条件有可能用不上。默认是升序asc 如果想降序的话desc
还可以select ename,sal from emp order by 2;第二个字段,但是可读性差 尽量不要这么写
数据处理函数/单行处理函数
lower 转换小写 select lower(ename)as ename from emp;
upper 转换大写
substr 取子串substr(ename,1,1)被截取字符串 起始位置从1开始 长度
length长度
trim去空格
round 参数rount(123.456,2)四舍五入默认不写去整,2保留两位 -1个位 -2 100 一般没有人写负
rand 随机数 round(rand()*100)取0-100
ifnull 空置处理函数
比如有个需求补贴是null的显示为0 select ename,ifnull(comm,0)from emp;
空值参加的数据运算的话最后结果还是空 所有数据库都是这么处理的,为了避免要用ifnull来处理
年薪 select ename,(sal+comm)*12 from emp;因为有null所以要
修改 select ename,(sal+ifnull(comm,0))*12 as yearsal from emp;
每个数据库中处理字符串方法都不太一样
mysql默认%Y-%m-%d 当输入字符串的时候 进行了转换data类型
select ename,hiredate from emp where hiredate=str_to_date(1980-12-17,'%Y-%m-%d');
数据库数据类型
int 整数型 varchar可变长度字符串 char定长字符串 date日期类型 double浮点型
案例
创建学生表 以后详细讲
create table t_student(
id int(10),name varchar(32),birth date
);
插入数据
insert into t_student(id,name,birth) values(1,'jack','1980-10-11')可以执行
虽然是varchar 但是格式和mysql默认日期格式相同存在自动类型转换
str_to_date通常使用在插入操作中,字段是date类型,不接受字符串varchar需要先转str_to_date成date后再插入才能成功
date_format 作用将日期类型date转换成具有特定格式的日期字符串varchar[date->varchar]
date_format(日期数据类型,‘日期格式’)
案例:查询员工的入职日期 以%m-%i-%Y ‘10-12-1980’的格式显示到窗口中
select ename,date_format(hiredate,'%m-%i-%Y ') as hiredate from emp
date_format函数主要使用在查询操作中。客户需要日期特定显示
第一天下午
分组函数 聚合函数 多行函数
sum求和 select sum(sal)from emp
avg
max
min
count 自动忽略空值 写上字段名 字段中不为空的个数 写*满足条件的所有 不管空不空
比如select count(*)from cmp where comm is null;
分组函数不能直接使用在where中;比如 where sal> avg(sal);
去除重复记录,当我们查询出来的有重复的希望去除重复可以
select distinct job from emp; distinct作用去除重复,只是将查询结果去重复不会该表
不能select ename,distinct job from emp;distinct前面不能写其他字段,distinct只能出现在所有字段的最前端
select distinct deptno,job from emp; 联合去重复deptno job看成一个字段
统计公司有多少个工作岗位 select count(distinct job)from emp;
分组查询
1、分组查询涉及到的两个字句是:group by和having
order by 表示通过哪个或者哪些字段进行排序
group by 表示通过哪个或者哪些字段进行分组
案例 找出每个岗位的最高薪水 先按照工作岗位分组使用max求每组最高薪水
select max(sal) from emp group by job;先按照job分组然后对每一组使用max(sal)求最高
以上查询结果是5条记录
select job,max(sal) from emp group by job 可以 因为正好job也是五个不同值
如果select后面加入ename呢,mysql语法可以,oracle报错。但是mysql返回是不正确的数据无意义返回的是ename回来的和max不匹配
重点如果DQL有group by的话select后面只能跟参与分组的字段和分组函数
14个人按job分5组案例。
2.3案例:计算每个部门的平均薪水[按照部门编号分组 对每一组求avg(sal)]
select dptno,avg(sal) as avgsal group by deptno;
2.4案例:不同工作岗位的最高薪水
select job,max(sal)from emp group by job;
变化计算不同部门中不同岗位的最高薪水,这种要怎么做。
select deptno,job,max(sal)from emp group by deptno,job;类似distinct deptno job看作一个去除了重复。两个字段分组看成一个字段,从而求出来不同部门中不同岗位的最高薪水
2.5案例找出每个工作岗位的最高薪水,除manager之外
select job,max(sal) from emp where job<>‘manager’group by job
2.6找出每个工作岗位的平均薪水,要求显示平均薪水》1500的
不能这么写select job,avg(sal)from emp where avg(sal)>1500 group by job
原因是顺序先from 后经过where语句过滤然后分组最后查询,where中如果使用分组函数会不行
修改为select job,avg(sal)from emp group by job having avg(sal)>1500
having:
having和where功能都是为了完成数据的过滤
where和having后面都是添加条件
where在group by之前完成过滤
having在group by之后完成过滤
效率问题,原则上尽量where过滤无法过滤的先分组后再过滤的用having
一个完整的DQL语句的总结:
select from where group by having order by
以上的关键字顺序不能变,执行顺序
1 from 从某张表中检索数据
2 where 经过某条件进行过滤
3 group by 然后分组
4 having 分组之后不满意再过滤
5 select 查询出来
6 order by 排序输出
连接查询 跨表查询 重点
查询的时候只从一张表检索数据,被称为单表查询
在实际开发中 数据并不是存储在一张表中的,是同时存储在多张表中,这些表和表之间存在关系,我们在索引的时候通常是需要将多张表联合起来取得有效数据,这种多表查询被成为连接查询或者叫跨表
连接查询根据出现年代分类 sql92 sql99主
连接查询根据连接方式可以分为
内连接
等值连接
非等值连接
自连接
外连接
左外连接 左连接
右外连接 右连接
全连接 很少使用
员工表 部门表
select ename,dname from emp,dept;
小知识点:在进行多表连接查询的时候,尽量给表起别名这样效率高 可读性高
select e.ename,d.dname from emp e,dept d;笛卡尔积
若两张表进行连接查询的时候没有任何条件限制,最终的查询结果总数是两张表ijlu条数乘积。
为了避免笛卡尔积现象发生,必须进行表连接的时候添加限制条件。
案例:查询每一个员工所在的部门名称,要求最终显示员工名和对应的部门名
ename deptno emp deptno deptname dept
注意:在连接查询的时候虽然使用了限制条件但是匹配的次数没有减少,还是56次14X4只不过这一次的结果都是有效记录。
SQL92语法 内连接中的等值连接
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
SQL99语法 内连接中的等值连接 主流 有点就是结构清晰 表连接独立出来了join on 对表连接不满意的话可以再追加where过滤
select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;
join前面省略了innner
非等值连接。
案例 找出每一个员工对应的薪水等级
emp员工表和salgrade工资等级表
select e.name,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
案例 找出每一个员工的上级领导,要求显示员工名以及对应的领导名
把它看成两张表
emp 员工表a
dmpno ename mgr
7369 smith 7902
14条 king没有老板
要把mgr的no换成人名
emp 领导表b 领导也是员工
select a.ename emp name,b.ename leadername from emp a join emp b on a.mgr=b.empno
自连接 innner也可以省略。
案例: 找出每一个员工对应的部门名称,要求部门名全部显示。有一个部门没有人
select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;
内连接:a b能够完全匹配的数据查出来被称为内连接
外连接
a和b表能够完全匹配的记录查询出来之外,除了内连接这些数据之外需要将a/b中无条件显示其中一张表 如果没有的话出null与之匹配,外连接的查询结果条数》=内连接的查询结果条数。
SQL99select e.ename,d.dname from emp e right join dept d on e.deptno=d.deptno;
right outer 可以省略outer
left outer可以省略outer
左右可以修改前后位置来切换left right
左/右 左边这张表 from后面/右边这张表join后面
为什么inner/outer可以省略,因为区分内外不是看这个而是看是否存在left/right若存在则是外连接,没有的话就是内连接。加上去的好处是增加可读性。
9案例 找出每一个员工对应的领导名,要求显示所有的员工
select a.ename empname,b.ename leadername from emp a left join emp b on a.mgr=b.empno
10案例:找出每一个员工对应的部门名称,以及该员工对应的工资等级,要求显示员工名 部门名 工资等级
多张表进行表连接的语法格式:
select
xxx
from
a
join
b
on
condition
join
c
on
condition
原理,a和b先join然后拿着a和c join并不是a和b join的结果和c连接
emp dept salgrade
emp
ename deptno sal
smith 20 800
allen 30 1600
ward 30 1250
jones 20 2975
martin 30 1250
……
dept
deptno dname
10 accounting
20
research
30
sales
40
operations
salgrade
grade losal hisal
1
700
1200
2
1201 1400
3
1401 2000
4
2001 3000
5
3001 9999
select
e.ename,d.dname,s.grade
from
emp e
join
dept d
on
e.deptno=d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal;
子查询
1.什么是子查询 select 语句潜逃select 语句
2.子查询可以出现在哪
select ..(select)
from.. (select)
where.. (select)
3.案例 找出薪水比公司平均薪水高的员工,要求显示员工名和薪水
select ename,sal from emp where sal 》 avg(sal);
上面错误,where后不能接分组函数。
where后面使用子查询。
第一步:找出公司的平均薪水
select avg(sal)from emp;
第二步:找出薪水大于平均薪水的员工信息
select ename,sal from emp where sal > (select avg(sal)from emp);
4.from后面使用子查询
案例:找出每个部门的平均薪水,而且要求显示平均薪水的薪水等级。
第一步 找出每个部门的平均薪水
select avg(sal)as avgsal from emp group by deptno;
第二步 将上面的查询结果当作临时表t,t表和salgrade s表进行表连接。
条件是 t.avgsal between s.losal and s.hisal
将查询结果放在from后面作为临时表
select
t.deptno,t.avgsal,s.grade
from
(select avg(sal)as avgsal from emp group by deptno) t
join
salgrade s
on
t.avgsal bewteen s.losal and s.hisal
5.在select后面使用子查询
select e.ename,(select d.dname from dept d where e.deptno=d.deptno) as dname from emp e
union可以合并集合(相加)
找出工作岗位是salesman和manager的员工
select ename,job from emp where job in (‘sales’,‘manager’)
字段个数要相同,oracle 类型字段要相同。mysql不是一个字段的揉成一个字段
select ename,job from emp where job='MANAGER'
union
select ename,job from emp where job='salesman'
limit 出现在sql语句最末尾
1.limit用来获取一张表中的某部分数据
2.limit只有在mysql数据库中存在不通用 特色
3.案例找出元员工表中前五条记录
select ename from emp limit 5;这条语句中的5表示从表中记录下标0开始,取5条等同于下面的sql
select ename from emp limit 0,5; //0可省略 limit起始下标,长度,起始下标没有指定默认0第一条开始。
4.案例找出公司中工资排名在前五名的员工。
思路:按工资降序排序取前五个
select ename,sal from emp order by sal desc limit 5;
5.找出工资排名在3-9名的员工
select ename,sal from emp order by sal desc limit 2,7;
6.mysql 中通用的分页sql语句:
每页显示3条记录
第一页:起始下标0 长度3
第二页:起始下标3 长度3
第三页:起始下标6 长度3
第四页:起始下标9 长度3
每页显示pagesize条记录
第pageNo页:(pageNo-1)*pagesize pagesize
通用的分页sql 只适用于mysql数据库
select
ename,sal
from
emp
order by
sal desc
limit
(pageSize-1)*pageSize,pageSize;