3.
数据库中仅有月薪字段(month_salary),要求查询所有员工的年薪,并以年薪(year_salary)输出:
分析:
- 查询操作中,字段可以参与数学运算
- as 起别名,但实际上可以省略
#以下两句效果完全一致
select month_salary as year_salary from emp
select month_salary year_salary from emp
4. 条件查询
#条件查询的语法
select
...
from
...
where 过滤条件;
带有
除了数学符号外,常见的条件
| between...and... | 等同于 >= and <= |
| is null | 为空 |
| is not null | 不为空 | | |
| in | 在指定的值当中 |
| not in | 不在指定的值当中 |
| exists | |
| not exists | |
| like | 模糊查询 |
in 和 or 的效率
我们知道, in的执行原理实际上是采用 = 和 or 的方式,
job in(‘MANAGER’,‘SALESMAN’,‘CLERK’)
等同于
job = ‘MANAGER’ or job = ‘SALESMAN’ or job = ‘CLERK’
sal in(1600, 3000, 5000)
等同于
sal = 1600 or sal = 3000 or sal = 5000
查询的列如果有索引或者主键,那么二者效率基本相当
否则
or的效率为O(n),而in的效率为O(log n), 当n越大的时候效率相差越明显(也就是说数据量越大的时候,in的效率越高)。
.1 and 和 or 优先级问题
找出薪资小于1500,并且部门编号是20或30的员工姓名、薪资、部门编号。
直接给出错误 SQL:
select
ename,sal,deptno
from
emp
where
sal < 1500 and deptno = 20 or deptno = 30;
结果是错的,有两个部门 30 且工资超过 1500 的也被查询了
分析:
- MS 中,and 的优先级大于 or
# 我们想要的执行顺序是 sal < 1500 and (deptno = 20 or deptno = 30)
# 实际的执行顺序是 (sal < 1500 and deptno = 20) or deptno = 30;
# 即系统先筛选出同时满足工资小于 1500 且部门 20 的人,再加上所有部分 30 的人后一起输出
sal < 1500 and deptno = 20 or deptno = 30;
# 由于 and 优先级高,系统先执行所有 and,因此执行顺序是(条件1 and 条件2)or(条件3 and 条件4 )
where 条件1 and 条件2 or 条件3 and 条件4
- 不用记忆优先级。遇到不确定的优先级时,用小括号来保证正确。
sal < 1500 and (deptno = 20 or deptno = 30)
模糊查询
模糊查询的语法格式如下:
select .. from .. where 字段 like '通配符表达式';
通配表达式也很简单,主要是
- % 代表任意多个字符。
- 下划线 “_” 代表任意一个字符。
order by排序
order by 关键字默认采用 asc 升序
#按照 sal 升序排列,如果 sal 相同的,再按照 ename 升序排列。
select empno,ename,sal from emp order by sal asc, ename asc;
distinct 去重
- distinct只能出现在所有字段的最前面。
- 且当distinct出现后,后面多个字段一定是联合去重的: 即将多个字段视为一个整体,允许部分重复,不允许整体重复。
数据处理函数
字符串处理相关之 upper/ucase、lower/lcase
# 查询所有员工名字,以大写形式展现
select upper(ename) as ename from emp;
#数据库是否对大小写敏感主要取决于操作系统.win 内不敏感,linux 内敏感
#若在 linux 内部署数据库,并且此时不知道表中的人名是大写、小写还是大小写混合,
#不妨直接将 ename 一整列都转大写,然后再用大写的人名去匹配,这样,只要确实存在这个人,不管大小写都能匹配出来
select ename, job, sal from emp where upper(ename) = 'SMITH';
截取字符串substr
语法:substr(‘被截取的字符串’, 起始下标, 截取长度)
有两种写法:
第一种:substr(‘被截取的字符串’, 起始下标, 截取长度)
第二种:substr(‘被截取的字符串’, 起始下标),当第三个参数“截取长度”缺失时,截取到字符串末尾
注意:起始下标从1开始,不是从0开始。(1表示从左侧开始的第一个位置,-1表示从右侧开始的第一个位置。)
练习:找出员工名字中第二个字母是A的
select ename from emp where substr(ename, 2, 1) = 'A';