---几个用于判断的函数
NVL(目标字段,默认值):对目标字段判断是否为空,为空则取默认值,否则取目标字段的值
NVL2(目标字段,默认值1,默认值2):判断目标字段是否为空,为空则取默认值2,不为空则取默认值1
--比如:
select e.*,
nvl(e.comm,0), --默认值的类型要跟目标字段一致
nvl2(e.comm,'有提成','无') --默认值1跟默认值2的数据类型需要一致,不需要跟目标字段一致
from emp e;
case when列上的判断
--语法结构1:
case 要判断的列/字段
[when 值1 then 结果1
when 值2 then 结果2
.....
else 其他结果]
--意思就是:
对某个列/字段(case后面)进行等值判断(when后面)
如果该字段的值 = when后面的这个值,那么就赋一个新的结果(then后面)
并将这个新的结果放在一个新生成的列中
--需要注意的是:
1、case when是作为要查询的信息放在select后面 --有新的列生成,一个case end就会生成一个新的列
2、这种语法结构只能做等值判断 --相当于把case后面的字段的值跟when后面的值进行等值比较
3、如果分支(一个when就是一个分支)写少了,那么新的列可能就会有空值
如果不写else,也可能有空值
4、最后的end不要忘,一个case end就会生成一个新的列
5、同时只能对一个字段进行判断(case后面只能是一个字段)
--比如:查询emp表中的员工的岗位,显示中文职称
select e.*,
case e.job
when 'CLERK' then '办事员'
when 'SALESMAN' then '销售'
when 'MANAGER' then '经理'
when 'ANALYST' then '分析员'
else '总裁'
end as "中文职称"
from emp e;
---对什么字段进行判断,就把这个字段写在case后面,判断的值是什么,就写在when后面,赋予新的结果是什么,就写在then后面
/
小练习一把:查询emp表中的员工的信息,给他们加薪,部门10的加500,部门20的加20%,部门30的加1000,其余的不加薪
显示员工信息以及加薪后的工资
/
select e.*,
case e.deptno
when 10 then e.sal + 500 --then后面可以是一个具体的值,也可以是一个表达式(算术,函数)
when 20 then e.sal * 1.2
when 30 then e.sal + 1000
else e.sal
end as new_sal
from emp e;
--语法结构2:
when 条件1.1 [and/or 条件1.2] then 结果1
[when 条件2.1 [and/or 条件2.2] then 结果2
......
else 其他结果]
--比如:上面的这个小练习
select e.*,
when e.deptno = 10 then e.sal + 500 --when后面的条件的写法跟之前学的where后面的写法一样
when e.deptno = 20 then e.sal * 1.2
when e.deptno = 30 then e.sal + 1000
else e.sal
end as new_sal2
from emp e;
--需要注意的是:
1、可以做等值判断,也可以做非等值判断
2、when后面就是一个类似于过滤的一个关系运算(要判断的字段 运算符 值)
--小练习一把:查询员工工资跟其部门的平均工资,工资高于平均工资的,工资加2000,否则加3000,显示员工信息,部门平均工资以及加薪后的工资
select f.
,
when f.sal > f.avg_sal then f.sal + 2000
else f.sal + 3000
end as new_sal
from (
select e.
,
avg(e.sal)over(partition by e.deptno) avg_sal
from emp e) f;
select e.*,
avg(e.sal)over(partition by e.deptno) avg_sal,
when e.sal > avg(e.sal)over(partition by e.deptno) then e.sal + 2000
else e.sal + 3000
end as new_sal
from emp e;
---decode():oracle独有
decode(目标字段,判断的值1,结果1[,判断的值2,结果2,........,其它结果])
--比如:查询emp表中的员工的岗位,显示中文职称
select e.*,
decode(e.job,
'CLERK','办事员',
'SALESMAN','销售',
'MANAGER','经理',
'ANALYST','分析员',
'总裁') as "中文职称"
from emp e;
--需要注意:
1、根据参数的个数来决定是否写了else
如果参数是 偶数 个,最后一个参数的值就表示 else 其它结果
如果参数是 奇数 个,就相当于没有写 else -- 可能会有空值
/*小练习一把:
查询emp表中的员工信息以及他们的工资等级,
等级的1工资加1000
等级的2工资加2000
等级的3工资加3000
等级的4工资加4000
其它的加500
显示员工的信息,工资等级,以及加薪后的工资
select e.,s.grade,
decode(s.grade,
1,e.sal + 1000,
2,e.sal + 2000,
3,e.sal + 3000,
4,e.sal + 4000,
e.sal + 500) as new_sal
from emp e
join salgrade s
on e.sal between s.losal and s.hisal;
--小练习一把:用case when 或者 decode 实现刚刚的行列转换
select s.year,
max(case q
when 1 then amt
end) q1,
min(case q
when 2 then amt
end) q2,
avg(case q
when 3 then amt
end) q3,
sum(case q
when 4 then amt
end) q4
from s
group by s.year
order by s.year;
select s.year,
max(decode(s.q, 1, amt)) q1,
min(decode(s.q, 2, amt)) q2,
sum(decode(s.q, 3, amt)) q3,
avg(decode(s.q, 4, amt)) q4
from s
group by s.year
order by s.year;