条件查询
根据条件进行筛选。
SELECT〈目标列组〉
FROM〈数据源〉
[WHERE 条件1 [AND [OR]] 条件2 ...]
设A为10、B为20。
操作符
查询工资大于等于2000的员工名字
select ename from emp where sal >= 2000;
查询工资在1100到5000的员工名及工资,包含1100和5000
select ename,sal from emp where sal between 1100 and 5000;
between and 适合某值在闭区间中
查询津贴为NULL的员工名,工资和津贴
select ename,sal,comm from emp where comm is null;
在前面查询这个表所有信息的时候,TURNER的津贴为0.00,注意,数据库中null表示有或没有,不能当做数值使用"="等操作符,0.00可以认为是有津贴,但是员工犯错误,扣光了。
查询津贴扣光或没有津贴的可以这样写
select ename,sal,comm from emp where comm is null or comm = 0.00;
或
select ename,sal,comm from emp where comm > 0.00;
读者自行尝试,不再截图。
查询薪资大于1000并且部门编号为20或30的员工名,薪资,部门编号
select ename,sal,deptno from emp where sal>1000 and deptno=20 or deptno=30;
看似没有问题,但是实际查询的是薪资大于1000并且部门编号为20的员工,以及部门编号为30的所有员工。原因是and的优先级高于or, sal>1000和deptno=20两个条件合并了。
可以通过加小括号的方式来进行限制,括号的优先级最高。
select ename,sal,deptno from emp where sal>1000 and (deptno=20 or deptno=30);
in 等同于 or,in 后面加的是等于多少的值所构成的数值元组,也可解决上面的问题
select ename,sal,deptno from emp where sal>1000 and deptno in (20,30);
select ename,sal,deptno from emp where sal>1000 and deptno in (20,30);
not in 就是不在元组中
模糊查询like
- %:任意多个
- _:任意一个
查询名字中包含O的员工名
select ename from emp where ename like '%O%';
查询名字第二个字母是'A'的员工名
select ename from emp where ename like '_A%';
如果查找名字中含下划线或百分号的,可以使用转义字符 '\'
select ename from emp where ename like '%\_%';
当然,本数据表里面没有,以后碰到了记得使用转义字符即可。
排序查询
SELECT〈目标列组〉 FROM〈数据源〉 [WHERE 条件1 [AND [OR]] 条件2 ...] [ORDER BY {列名 | 表达式 | 位置}
查询工作岗位是 'MANAGER'的员工,并按工资升序排列
select * from emp where job = 'MANAGER' order by sal;
默认升序,需要降序添加关键字 desc 即可。 使用asc是升序,你可以像我一样省略。
多条件,逗号隔开,先按前,再按后。
查询员工姓名和工资,并按工资升序排列,如果工资相同,按名字降序排列。
select ename,sal from emp order by sal,ename desc;
位置,按结果的第几列排序,健壮性太差,位置一换就不行了,尽量不用。
select ename,sal from emp order by 2;
分组查询
SELECT〈目标列组〉 FROM〈数据源〉 [WHERE 条件1 [AND [OR]] 条件2 ...] [ORDER BY {列名 | 表达式 | 位置} [GROUP BY {列名 | 表达式 | 位置} [HAVING 条件子句]
分组函数
- count 计数
- sum 求和
- avg 平均值
- max 最大值
- min 最小值
分组函数自动忽略null
查询津贴有几种情况
select count(comm) from emp;
从前面可以看到,comm除了null还有四个。
当出现group by时,select 之后只能加分组字段以及分组函数
数据错误
按多个字段分组
查询每个部门不同工作岗位的最高薪资
分组函数自动忽略null
select deptno,job,max(sal) from emp group by deptno,job;
分组函数不可直接使用在where子句中
查询工资高于平均工资的员工的名字和工资。
select ename,sal from emp where sal > avg(sal);
解决办法见子查询一节
查询每个工作岗位的最高薪资
select max(sal) from emp group by job;
分组函数在分组之后运行,先按job分组,之后再算每一组的最大值。
having 分组后的数据再次过滤
查询每个部门最高薪资,仅显示大于2900的部门编号及最大薪资。
select deptno,max(sal) from emp group by deptno having max(sal) > 2900;
运行顺序:
from 子句 -> where 子句 -> group by 子句 ->having子句 -> select列 子句 -> order by 子句
where 和having的选择
having的效率是比较低的
select deptno,max(sal) from emp where sal > 2900 group by deptno;
上面也可以完成“查询每个部门最高薪资,仅显示大于2900的部门编号及最大薪资”, 而且where子句在 group by 子句前执行,过滤掉后再进行分组时会少写数据,但是having是在分组之后再运行。
所以,能用where优先使用where,不行再使用having
查询每个部门平均薪资,仅显示大于2900的部门编号及平均薪资
select deptno,avg(sal) from emp group by deptno having avg(sal) > 2900;
where子句是无法办到的,原因还是执行顺序。
去重
除了分组,还可以使用关键字 distinct 来进行去重。
select distinct job from emp;
注:distinct只能出现在所有字段的最前方,多个字段则表示后面所有字段看做合并字段进行去重。