MySQL之单表查询
本章正式进入MySQL中实际操作
本章是没有特别需要理解的内容 ,想要学好就的练好,经常练。
一,简单查询
关键词:select ,from,as
你需要提前记住的:
1.所有的sql语句以分号结尾,不区分大小写
2.在所有数据库中,字符串统一使用单引号‘’
3.select语句一律不会改变表的结构
4.数据库中的null就是什么都没有
以上注意事项若遇到,会再次说明
1. 查询一个字段
(字段的概念在第二章有解释)
select 字段名 from 表名;
2. 查询多个字段
select 字段名,字段名,....from 表名;
3. 查询所有字段
select * from 表名;
尽量不要使用*来进行查询,因为会先将*变为字段名再进行查询,会使效率低下
4. 给查询的字段起别名
select deptno , dname as deptname from dept;
as 关键词用于起别名(可省略,如下面一行代码)
select deptno , dname deptname from dept;
假设起别名是,别名中带有空格该怎么办?
给别名加单引号整体变成字符串
select deptno , dename 'dept name' from dept;
5. 列参和数学计算
select ename , sal*12 as yearsal from emp;
二、条件查询
语法格式:
select
字段1,字段2,.........
from
表名
where
条件;
1.= , <>/!= , < , > , <= , >=
查询工资等于800元的员工编号
select
empno
from
emp
where
emp.sal=800;
其余条件与’=‘的用法类似
特别说明一下:<>在数据库中是不等于的意思
2.between…and…(两值之间)
等同于 >= and <= 所以包含边界值
between...and...必须左小右大,否则报错
以下段代码查询结果相同
select
empno,ename,sal
from
emp
where
emp.sal between 2450 and 3000;
select
empno,ename,sal
from
emp
where
emp.sal >= 2450 and emp.sal <= 3000;
3.is / is not
用来对null进行处理,如果用=处理null会报错,因为数据库里的null不是一个值,真的什么都没有。
select
ename,comm
from
emp
where
emp.comm is null;
is not 的用法同理,就不再赘述。
4.and和or
and:并且
or:或者
such:查询工作岗位是’MANAGER’,并且工资大于2500的员工信息
select
e.ename,e.job,e.sal
from
emp e
where
e.job='MANAGER' and e.sal>2500;
such:查询工作岗位是MANAGER和SALESMAN的员工
select
e.ename,e.job
from
emp e
where
e.job='MANAGER' or e.job='SALESMAN';
思考:and和or同时出现时,有优先级问题吗
such:查询工资大于2500,并且部门编号为10或20的员工。
如果写成:
select * from emp where sal >2500 and deptno=10 or deptno=20;
在第一行和第五行中工资都小于2500,违背了题意
and的优先级高于or,会先执行and
所以上面代码的意义是:找出工资大于2500并且部门编号为10的员工,或者部门编号为20的员工
正确的写法应该是:
select * from emp where sal >2500 and (deptno=10 or deptno=20);
5.in(包含,相当于多个or)
such:查询工作岗位是MANAGER和SALESMAN的员工
select
e.name,e.job
from
emp e
where
job in('MANAGER','SALESMAN'); //等同于job='MANAGER' or job='SALESMAN';
not in(不包含) 同理,所以不做赘述。
6.not(取非主要用在is或in中)
such:is null / is not null / in / not in
7.like(模糊查询,支持%或下划线匹配)
%: 匹配任意多个字符
_ : 任意一个字符
such:找出名字中含有0的
select
e.ename
from
emp e
where
e.ename like '%0%';
such:找出名字中以T结尾的
select
e.ename
from
emp e
where
e.ename like '%T';
such:找出名字中第二个字母是A的
select
e.ename
from
emp e
where
e.ename like '_A%';
such:找出名字中有’_'的
select
e.ename
from
emp e
where
e.ename like '%\_%';
such:找出名字为五个字母,且第四个字母为M的
select
e.ename
from
emp e
where
e.ename like '___M_';
三,查询后排序
1.order by(关键词)
默认升序排序
such:查询所有员工薪资,并排序
select
e.ename,e.sal
from
emp e
order by
sal;
2.desc(指定降序)
格式:order by 字段名 desc
select
e.ename,e.sal
from
emp e
order by
sal desc;
3.asc(指定升序)
格式:order by 字段名 asc
select
e.ename,e.sal
from
emp e
order by
e.sal asc;
4.按照多个字段排序
order by 字段1,字段2,......;
字段靠前的起主导作用,先按照该字段进行排序,只有该字段结果相同时,才启用下一个字段排序,剩余字段以此类推。
such:查询员工名字和薪资,要求按照薪资升序,如果薪资一样的话,再按照名字升序排序。
select
e.ename,e.sal
from
emp e
order by
e.sal asc,e.ename asc;
(重点)5.sql语句中关键词的运行顺序
目前所学到的关键词:select,from,where,order by
select
...
from
...
where
...
order by
...
执行顺序:from→where→select→order by
order by 始终最后执行
四,单行处理函数(数据处理函数)
特点:一个输入对应一个输出。
与单行处理函数相对的是:多行处理函数(多个输入对应一个输出)
1.lower() 转小写
select
lower(e.ename)
from
emp e
注意:字段名改变了,可以起别名
2.upper() 转大写
与lower函数类似,不在赘述。
3.substr() 取子串
用法:substr(被截取的字符串,起始下标,截取的长度)
select
substr(e.ename,1,1)
from
emp e;
分析查询结果:输出的是ename的首字母,所以数据库中起始下标是1,而不是0.
例题:找出员工名字中第一个字母是A的员工信息。
way 1:模糊查询
select
e.empno,e.ename
from
emp e
where
e.ename like 'A%';
way 2:substr(截子串)
select
e.empno,e.ename
from
emp e
where
substr(e.ename,1,1)='A';
扩展例题:输出员工名且首字母大写
扩展例题:输出员工名且首字母大写
select
concat(upper(substr(e.ename,1,1)),lower(substr(e.ename,2,length(e.ename)-1))) as result
from
emp e;
concat(str1,str2,.....)字符串拼接,在数据库中字符串不能用+进行拼接。
length(字段名)取长度
4.trim() 取前后空格
select
e.ename
from
emp e
where
e.ename=trim(字符串变量);
//字符串变量=' xxxxxxx '
5.round() 四舍五入
用法:round(数,保留小数点后几位(可为负数))
示例1:
select
round(125.65,0) as result //保留0位就是取整
from
emp;
示例2:
select
round(125.65,-1) as result //保留小数点后-1位就是保留十位
from
emp;
6.rand() 生成随机数
生成的随机数范围为0~1
示例1:
select
rand()
from
emp;
示例2:输出100以内的随机数
select
round(rand()*100,0) as randNum
from
emp;
7.ifnull() 将null转换成一个具体值
用法:ifnull(数据,期望转换成为的值)
在所有数据库中,只要有null参与的数学运算,最终结果就是null
例:计算员工的年薪。(年薪=(月薪+月补助)*12)
select
e.ename,(e.sal+ifnull(e.comm,0))*12 as yearsal
from
emp e;
8.case…when…then…when…then…else…end
例:当员工的工作岗位为’MANAGER’时,工资上调10%,当工作岗位为’SALESMAN’时,工资上调50%,其余正常(不修改数据库内部数据)
select
e.ename,e.job,
case e.job
when'MANAGER' then e.sal*1.1
when'SALESMAN' then e.sal*1.5
else sal
end as newsal
from
emp e;
五,分组函数
分组函数特点:输入多行,输出一行
注意:1.分组函数在使用时必须先分组后才能使用
注意:2.分组若未说明如何分组,则默认将整张表分为一组
1.分组函数中常用的五个函数
1.count(字段名) 对该字段中的记录个数进行计数
2.sum(字段名) 对该字段中的记录数据进行求和
3.avg(字段名) 对该字段中的记录数据进行求平均数
4.max(字段名) 对该字段中的记录数据进行求最大值
5.min(字段名) 对该字段中的记录数据进行求最小值
接下来不会对以上函数单独进行举例。
2.注意事项
(1)分组函数自动忽略null,所以不许对null进行提前处理
such:注意emp表中的COMM字段中的非null个数
对COMM字段进行count操作
select count(comm) from emp;
输出结果为COMM字段中,记录非空的数据个数。
(2)分组函数中count(*)和count(字段名)的区别
什么都别说了,直接先上代码看区别:
select count(*) from emp;
解释:
count(*):统计的是表中的总行数(当有一行数据全为空时,才会省略,但数据库中不存在有一行数据全为空)
count(字段名):统计该字段下所有部位null的总数
(3)分组函数可以组合一起用
select count(*),sum(sal) from emp;
(4)分组函数不能直接使用在where子句中
such:找出比最低工资高的员工
select
ename,sal
from
emp
where
sal>min(sal);
报错:分组函数的无效使用
解释:
将目前所学的关键词,知道了“执行顺序”和“注意1.分组函数在使用时必须先分组后才能使用”,就能够解释了,因为where关键词是在group by关键词执行前执行的,所以此时还未分组(代码中虽然未直接说明group by,但未说明会默认将一张表当成一组)
select
...
from
...
where
...
group by
...
order by
...
执行顺序:from → where → group by → select → order by
知道关键词的执行顺序和
3.分组查询(group by)
格式:
select
...
from
...
group by
...
such:找出每个工作岗位的最高薪资
select
job,max(sal) as MaxSal
from
emp
group by
job;
(1)在一条select语句中,如果有group by语句的话,select后面跟:参加分组的字段,分组函数
such:找出每个工作岗位的工资和
select job,sum(sal) from emp group by job;//能够正常运行
select job,sum(sal),ename from emp group by job;//会报错
(2)having关键词
使用having关键词可以对分完组的数据进行进一步的过滤。
having不能单独使用,必须联合group by使用。
having不能够代替where。
such:找出每个部门最高薪资,要求显示的薪资大于3000
select
deptno,max(sal)
from
emp
group by
deptno
having
max(sal)>3000;
但是使用having的sql语句的效率较低,可以改进
使用having的代码逻辑是:先分组再将大于3000的筛选
使用where的代码逻辑是:先将大于3000的筛选,然后在分组
select
deptno,max(sal)
from
emp
where
sal>3000
group by
deptno;
所以能够使用having就尽量不要使用having,但也有必须使用having的例子
such:找出每个部门的平均薪资,要求显示的平均薪资大于2000
select
deptno,avg(sal)
from
emp
group by
deptno
having
avg(sal)>2000;
六,distinct关键词
作用: 去除查询结果中的重复记录。(原本数据不会被修改)
用法: distinct 字段名
select distinct job from emp;
distinct只能出现在所有字段的最前发,表示所有字段联合起来去重
当distinct出现在某个字段后
select
ename,distinct job
from
emp;
解释:ename有14行,distinct job只有5行,不能匹配。
正确用法
select
distinct ename,job
from
emp;
例:统计一下工作岗位的数量
select
count(distinct job)
from
emp;
总结
单表查询在数据库中非常重要,对于我来说,有点分不清order by和group by的用法,总是会搞混,所以需要大量的练习,不能够懒。
接下来的连接查询会比单表查询更加重要,注意练习,会回顾。