ORACLE的一些查询语句

时间:2022-03-06 23:25:40

学了几天的oracle现在做总结如下:

1  刚安装好oracle19g在命令行以scott用户登录的时候,一般要对其进行解锁,其语句如下

首先以dba的身份登录连接到该数据库  sqlplus sys/orcl   as sysdba

连接后执行如下语句:alter user scott account unlock

输入该语句后会让重新输入密码:一般是tiger ,可以随意设但是自己要记得所设密码啊呵呵

然后再重新输入密码进行确认,这样以scott用户登录了嘿嘿,其登陆语句是:sqlplus

然后让输入密码,输入你刚才所设密码即可。如果输入正确即可进行一些数据库的操作了呵呵

2 以下是一些查询语句:

a  从emp表中查询出每个人的员工编号,名字,月薪,年薪(不包含奖金),职位,奖金 并且每个字段定义别名

 select empno 编号,ename 姓名,sal 月薪,sal*12 年薪,job 职位,comm 奖金 from emp;

b 从emp表中查询出每个人的员工编号,名字,月薪,年薪(包含奖金),职位,奖金 并且每个字段定义别名

 select empno 编号,ename 姓名,sal 月薪,(sal+comm)*12 年薪,job 职位,comm 奖金 from emp;

*注意喽:此时由于comm有的是空的,oracle对于有null值的表达式其值一定为空滴呵呵所以要注意了,要想知道怎么解决还得继续往下看哦呵呵,建议:在实际开发中不要使用null值的字段

c 查询出薪水大于1500的人的编号,名字,职位,月薪,奖金,年薪

 select empno 编号,ename 姓名,sal 月薪,sal*12 年薪,job 职位,comm 奖金
 from emp
 where sal > 1500;

d 查询出名字不等于SMITH的人的编号,名字,职位,月薪,奖金,年薪

 select empno 编号,ename 姓名,sal 月薪,sal*12 年薪,job 职位,comm 奖金
 from emp
 where ename <> 'SMITH';

注意:在oracle中字符串是区分大小写的

e 求出薪水在1500到3000之间的人的薪水

select sal from emp
where sal between 1500 and 3000;

f 查询出名字中包含a的人的信息

select * from emp
where lower(ename) like '%a%';

注:lower()是把字符串全部转换为小写的,upper()是把字符串全部转换为大写的

g 查询出倒数第三个字符不为Y的人的信息

 select * from emp
 where ename not like '--Y%';

h 按照员工月薪由高到低的顺序进行排列后的员工的信息

select * from emp
order by sal desc;

注:desc是按降序排,asc是按升序排,默认为升序

i 查询出薪水大于1200并且入职日期在1981-04-02之后的人的编号,名字,月薪,年薪(不包含奖金),入职日期,格式化中国人能接受的日期形式

select empno,ename,sal,sal*12 annual_sal,hiredate,to_char(hiredate,'YYYY-MM-DD') from emp
  where sal>1200 and to_char(hiredate,'YYYY-MM-DD')>'1981-04-02'

注:to_char() 可把字符串转换成指定格式的日期   to_date()可把日期转换成数据库中的日期形式,其用法会在下文中提到

j 求出工资在公司的平均工资之上的人的信息

select * from emp
where sal > (select avg(sal) from emp );

注:avg(sal)是求平均工资

k  从emp表中查询出每个人的员工编号,名字,月薪,年薪(包含奖金),职位,奖金 并且每个字段定义别名

 select empno 编号,ename 姓名,sal 月薪,(sal+nvl(comm,0))*12 年薪,job 职位,comm 奖金 from emp;

注:大家看到了吧,用nvl()这个方法就可以去掉上述中奖金为空年薪也为空的现象了,nvl()是专门用来处理null值的呵呵

l 求出每个人的编号,名称,工资,入职日期,部门编号,部门名称及部门所在地

方法一: select e.empno,e.ename,e.sal,e.hiredate,e.deptno,dname,loc
from emp e,dept d
where e.deptno = d.deptno;

方法二: select e.empno,e.ename,e.sal,e.hiredate,e.deptno,dname,loc
 from emp e join dept d on e.deptno = d.deptno;

注:此时where后是两个表之间的连接条件,建议最先写连接条件,以免遗忘呵呵

方法二中用到了join  on来表示两表之间的连接,on后面写连接的条件,如果还有其他的条件则放where后面

m 查询工资大于公司平均工资,且名字中不包含a的,并且入职日期大于1982-07-07的员工的编号,名称,月薪,年薪,部门编号,部门名称,部门所在地  并且按照薪  水降序进行排列

方法一: select e.empno,e.ename,e.sal,(e.sal+nvl(e.comm,0))*12 ,e.deptno,dname,loc
from emp e,dept d
where e.deptno = d.deptno
and sal > (select avg(sal) from emp)
and lower(e.ename) not like '%a%'
and hiredate > to_date('1982-07-07','yyyy-mm-dd')
order by sal desc;

方法二: select e.empno,e.ename,e.sal,(e.sal+nvl(e.comm,0))*12 ,e.deptno,dname,loc
 from emp e join dept d on e.deptno = d.deptno
 where sal > (select avg(sal) from emp)
 and lower(e.ename) not like '%a%'
 and hiredate > to_date('1982-07-07','yyyy-mm-dd')
 order by sal desc;

注:注意子查询哦,很绕的,小心给绕进去了呵呵

n 求出每个人的名字,工资,职位,编号,以及对应的直接领导的名字,工资,职位,编号信息

select e.ename,e.sal,e.job,e.empno,e1.ename,e1.sal,e1.job,e1.empno
 from emp e join emp e1 on e.mgr = e1.empno;

o  求每个人的工资属于哪个级别

select grade from emp join salgrade on sal between losal and hisal;

p 求出工资在公司的平均工资之上,并且入职日期在1981-06-04之后,并且名字中包含a的人的编号,姓名,工资,等级

方法一 : select empno,ename,sal,grade from emp ,salgrade
where sal between losal and hisal
and sal > (select avg(sal) from emp)
and hiredate > to_date('1981-06-04','yyyy-mm-dd')
and lower(ename) not like '%a%';

方法二: select empno,ename,sal,grade from emp join salgrade on sal between losal
 and hisal
 where sal > (select avg(sal) from emp)
 and hiredate > to_date('1981-06-04','yyyy-mm-dd')
 and lower(ename) not like '%a%';

q 查出名字里面第二个字母不是A的人的信息以及所在的部门情况以及工资的等级情况

方法一: select e.* ,dname,loc ,grade
from emp e,dept d,salgrade s
where e.deptno = d.deptno and e.sal between s.losal and s.hisal
and upper(e.ename) not like '-A%';

方法二: select e.* ,dname,loc ,grade
 from emp e join  dept d on e.deptno = d.deptno join  salgrade s
 on e.sal between s.losal and s.hisal
 where substr(upper(ename),2,1) != 'A';

r 每个人和对应的经理人的信息(包含king)

select e.* from emp e left join emp m on e.mgr = m.empno;

s 求出每个部门平均薪水等级

select grade ,deptno,avg_sal from (
 select avg(sal) avg_sal,deptno from emp group by deptno) join salgrade
 on avg_sal between losal and hisal;

t 求平均薪水最高的部门编号
 select deptno from (
 select deptno, avg(sal) avg_sal from emp group by deptno)
 where avg_sal = (select max(avg(sal)) from emp group by deptno);

u 求平均薪水最高的部门名称
 select dname from dept
 where deptno = ( select deptno from (
  select e1.deptno, avg(sal) avg_sal from emp e1 group by e1.deptno) e
  where avg_sal = (select max(avg(sal)) from emp group by deptno));

v 求平均薪水等级最低的部门部门名称

要想求平均薪水最低的部门名------->首先要求平均薪水最低的部门的部门号 -------->最低的平均薪水级别------->每个部门的平均薪水级别------>求每个部门的平均薪水

1 每个部门的平均薪水

select avg(sal) ,deptno from emp
group by deptno;

2  每个部门的平均薪水级别

select grade,deptno from (select avg(sal) avg_sal,deptno from emp
group by deptno) a,salgrade s
where avg_sal between s.losal and s.hisal;

3 最低平均薪水级别

select min(grade) from
(select grade,deptno from (select avg(sal) avg_sal,deptno from emp
group by deptno) a,salgrade s
where avg_sal between s.losal and s.hisal);

4    平均薪水最低的部门的部门号

select deptno from
(select grade,deptno from (select avg(sal) avg_sal,deptno from emp
group by deptno) a,salgrade s
where avg_sal between s.losal and s.hisal) a
where grade = (
 select min(grade) from
 (select grade,deptno from (select avg(sal) avg_sal,deptno from emp
 group by deptno) a,salgrade s
 where avg_sal between s.losal and s.hisal));

5   平均薪水最低的部门名
  select dname from dept
 where deptno in(
 select deptno from
 (select grade,deptno from (select avg(sal) avg_sal,deptno from emp
 group by deptno) a,salgrade s
 where avg_sal between s.losal and s.hisal) a
 where grade = (
  select min(grade) from
  (select grade,deptno from (select avg(sal) avg_sal,deptno from emp
  group by deptno) a,salgrade s
  where avg_sal between s.losal and s.hisal)))
 ;

w 薪水最高的前5个人
 select rownum r,ename,empno,sal from(
 select ename,empno,sal from emp order by sal desc)
 where rownum <6;

注:oracle中用rownum来进行分页,sqlserver用top来进行分页,mysql则用limit来进行分页

而且在oracle中如果有order by 和rownum的话会先进行分页后排序,所以要注意喽,下面教给大家一些小窍门:

1.先不管分页 写出要查询的sql语句(注意如果要求排序一定要包含排序语句)  -----sql
 2.然后将该sql语句看成一张子表 给这种字表加上一个变为实字段的伪字段
  即select rownum  r,a.* from (sql) a
  得到的是一个拥有顺序的结果
 3.最后将该结果再次看成一张子表 对该表进行分页 利用的已经变为实字段的伪字段r类获取 
 select * from (2的sql语句) where r between ? and ?  其中第一个问号指从哪开始 第二个指的到哪结束

 

以下这几个就用到上面的窍门了哦呵呵

x *按薪水从高到低排列的第6个到第10个人的信息

 select * from (
 select rownum r,a.* from(
 select ename,empno,sal from emp order by sal desc) a )
 where r between 6 and 10;

y 查询出名字中包含a的,并且薪水大于1200,并且入职日期大于1979-01-03的人里面薪水由高到低顺序排名的3到7人的信息
select * from (
select rownum r,a.* from(
select * from emp
where lower(ename) like '%a%'
and sal > 1200
and hiredate > to_date('1979-01-03','yyyy-mm-dd')
order by sal desc) a )
where r between 3 and 7;

z 查询出名字中包含a的,并且薪水大于1200,并且入职日期大于1979-01-03的人里面薪水由高到低顺序排名的3到7人的编号,姓名,职位,月薪,年薪,部门名称,所在地以及工资的等级情况
select * from(
select rownum r,a.* from(
select empno,ename,job,sal,(sal+nvl(comm,0))*12 annual_sal,dname,loc,grade
from emp e,dept d,salgrade s
where e.deptno=d.deptno
and e.sal between s.losal and s.hisal
and lower(ename) like '%a%' and sal >1200
and hiredate > to_date('1979-01-03','yyyy-mm-dd')
order by sal desc) a)
where r between 3 and 7;

嗯好了就先写这么多吧呵呵