2018/12/19 oracle-sql練習
--nvl()第一個為空則返回第二個
select nvl(comm,0) comm
from emp;
--nvl2 如果第一個數不為空,返回第二個數,否則返回第三個數
select nvl2(comm,comm,0) comm
from emp;
--nullif 兩個數相等為空 不等 返回第一個數
select nullif(10,40)
from dual;
--時間格式
select to_char(sysdate,'yyyy-mm-dd day hh24:mi:ss am')
from dual;
--coalesce()返回第一個不為空的引數,引數個數不限制
select coalesce(10,20,30)
from dual;
--case關鍵字的使用
select ename,deptno,
(
case deptno
when 10 then 'asd'
when 20 then 'dasd'
when 30 then 'da'
else 'no' end
) deptname
from emp;
--decode關鍵字的使用
select ename,deptno,
decode(deptno,
10,'銷售部',
20,'技術部',
30,'管理部'
) deptname
from emp;
--hello->ello
select trim('h' from 'hello')
from dual;
--' Hello '->'Hello'
select trim(' Hello ')
from dual;
--'bllb'->'ll'
select trim('b' from 'bllb')
from dual;
--'hello '->'hello'
select trim('hello')
from dual;
--查詢員工及其經理編號,沒有經理編號的顯示為‘no manager’
select ename,nvl(to_char(mgr),'no manager') mgr
from emp;
--查詢員工入職日期格式為 月份/年份
select to_char(hiredate,'mon/yy')
from emp;
--查詢員工工資,計算稅:工資<1000稅率0 1000<工資<2000 稅率10% 2000<工資<3000稅率15% 工資>3000 稅率20%
select ename,sal,
case trunc(sal/1000)
when 0 then sal*0
when 1 then sal*0.1
when 2 then sal*0.15
else sal*0.2 end 稅
from emp;
--查詢僱員的ename和sal,sal格式化成15個字元長度,左邊用$填充,列標籤為SALARY
select ename,lpad(sal,15,'$') SALARY
from emp;
--多表查詢,員工姓名,編號,部門名稱
select e.ename,e.empno,d.dname
from emp e
left join dept d
on e.deptno=d.deptno;
select * from dept;
--查詢在芝加哥工作,並且獎金不為空的員工姓名,工作地點,獎金
select e.ename 姓名,d.loc 工作地點,e.comm 獎金
from emp e
left join dept d
on e.deptno=d.deptno
where e.comm is not null and d.loc = 'CHICAGO';
--查詢姓名帶有‘A’的員工姓名,工作地點
select e.ename,d.loc
from emp e
left join dept d
on e.deptno=d.deptno
where e.ename like '%A%';
--外部連結,(+)能增加一個萬能的行,值為空,可以和另一個表中不滿足條件的行相連線
select e.ename,d.loc,d.deptno,d.dname
from emp e,dept d
where e.deptno(+)=d.deptno
order by e.deptno;
--right join可以將右邊加入的表中所有行查詢出來包括不符合條件的。查詢結果與上例外部連線結果相同
select e.ename,d.loc,d.deptno,d.dname
from emp e right join dept d
on e.deptno=d.deptno
order by e.deptno;
--自連線,查詢員工姓名和該員工的上級的姓名
select e.ename 姓名,a.ename 上級姓名
from emp e,emp a
where e.mgr=a.empno;
--inner join
select e.ename name,a.ename mgr_name
from emp e full join emp a--full join顯示兩張表中所有行(即使不符合條件)
on e.mgr=a.empno;
--分組和分組函式的使用
--查詢部門號為10的最高工資
select max(sal) 最高工資,deptno
from emp
where deptno=10
group by deptno;
--查詢部門編號為20 的平均工資和月薪總和
select avg(sal) 平均工資,sum(sal) 工資總和
from emp
where deptno=20
group by deptno;
--查詢CHICAGO的工作人數,最高工資和最低工資
select count(*) 人數,max(sal) 最高工資,min(sal) 最低工資,loc 工作地點
from emp natural join dept
where loc='CHICAGO'
group by loc;
--查詢員工有幾種工作崗位
--可以直接用distinct關鍵字去除重複
select distinct job
from emp;
--也可以用group by
select job
from emp
group by job;
--查詢每個部門的平均工資
select avg(sal) 平均工資,dname 部門名稱
from emp natural join dept
group by dname
--查詢每個部門的部門編號,部門名稱,部門人數,
--最高工資,最低工資,工資總和,平均工資
select deptno,dname 部門名稱,count(*) 部門人數,
max(sal) 最高工資,min(sal) 最低工資,
sum(sal) 工資總和,avg(sal) 平均工資
from emp natural join dept
group by (deptno,dname);
--查詢部門人數大於2的部門編號,部門名稱,部門人數
select deptno 部門編號,dname 部門名稱,count(*) 部門人數
from emp natural join dept
group by deptno,dname
having count(*)>2;
--查詢部門平均工資大於2000,且人數大於2的
--部門編號,部門名稱,部門人數,部門平均工資,
--並按照部門人數升序排序
select avg(sal) 平均工資,count(*) 人數,deptno
,dname
from emp natural join dept
group by deptno,dname
having count(*)>2 and avg(sal)>2000;
--查詢平均工資的最大值
select max(avg(sal))
from emp
group by deptno;
--查詢部門平均工資在2500元以上的部門名稱及平均工資。
select avg(sal),dname
from emp natural join dept
group by dname
having avg(sal)>2500;
--查詢崗位名稱不是以'SA'開頭並且平均工資大於2500的崗位名稱和平均工資,按照平均工資降序排序
select avg(sal),job
from emp
where job not like 'SA%'
group by job
having avg(sal)>2500
order by avg(sal) desc;
--查詢部門人數在2人以上的部門名稱、最高工資、最低工資
--並對求得的工資進行四捨五入到整數
select dname,round(max(sal),0),round(min(sal),0)
from emp natural join dept
group by dname
having count(*)>2;
--查詢崗位不為SALESMAN,工資和大於等於2500的
--崗位及每種崗位的工資和
select job,sum(sal)
from emp
where job <> 'SALESMAN'
group by job
having sum(sal)>=2500;
--顯示經理號碼和經理姓名,這個經理所管理
--的員工的最低工資,沒有經理的king也要顯示
--不包括最低工資小於3000的,按最低工資降序排序
select e.ename 經理,e.empno 經理編號,min(ee.sal) 所管理員工的最低工資
from emp e left join emp ee
on e.empno=ee.mgr
group by e.ename,e.empno
having min(ee.sal)>=3000
order by min(ee.sal) desc;
--寫一個查詢,顯示每個部門最高工資和最低工資的差額
select e.deptno,dname,max(sal)-min(sal) 最高最低差額
from emp e join dept d on e.deptno=d.deptno
group by e.deptno,dname;
--查詢入職日期比10部門任意一個員工晚的員工姓名
--、入職日期,不包括10部門員工
--寫法一
select ename,hiredate,deptno
from emp
where hiredate> any(select hiredate
from emp
where deptno=10
)and
deptno <> 10;
--寫法二 查詢出入職日期晚於10部門的任意一個員工的入職日期,那麼只需求出10部門中
--員工最早(小)的入職日期,並且比最小日期大,那麼就是比任意10部門的員工入職日期晚(大)。
select ename,hiredate,deptno
from emp
where hiredate>(select min(hiredate)
from emp
where deptno=10
group by deptno) and
deptno <> 10;
--查詢入職日期比10部門所有員工晚的員工姓名
--入職日期,不包括10部門員工
--寫法一
select ename,hiredate,deptno
from emp
where hiredate >all(select hiredate
from emp
where deptno=10)and
deptno <> 10;
--寫法二 大於10部門中入職日期最晚的員工的入職日期,那麼就比所有10部門的員工入職日期大(晚)
select ename,hiredate,deptno
from emp
where hiredate > (select max(hiredate)
from emp
where deptno=10
group by deptno)and
deptno <> 10;
--查詢職位和10部門任意員工職位相同的員工姓名,職位,不包括10部門的員工
--寫法一
select ename,job,deptno
from emp
where job in (select job
from emp
where deptno=10)and
deptno <> 10;
--寫法二 in(..) 和 = any(..)效果相同
select ename,job,deptno
from emp
where job = any(select job
from emp
where deptno=10)and
deptno <> 10;
--查詢職位及經理和10部門任意一個員工職位
--及經理相同的員工姓名,職位,不包括10部門員工
select ename,job,mgr
from emp
where (job,mgr) in (select job,mgr
from emp
where deptno=10)and
deptno <> 10;
--查詢職位及經理和10部門任意一個員工職位
--或者經理相同的員工姓名,職位,不包括10部門員工
select ename,job,mgr
from emp
where job in (select job
from emp
where deptno=10)
or
mgr in(select mgr
from emp
where deptno=10)
and
deptno <> 10;