oracle基础案例(2)

--1.找出部门10中的经理(MANAGER)和部门20中的普通员工(CLERK);
select * from emp where 
      (job='MANAGER' and deptno=10) or (job='CLERK' and deptno=20);
--2.分别用case和decode函数列出员工所在的部门,例如:deptno=10显示'部门10';
select  case deptno when 10 then '部门10'   when 20 then '部门20'  
                    when 30 then '部门30'   when 40 then '部门40' end 部门
from emp
--------------------------
select decode(deptno,10,'部门10',20,'部门20',30,'部门30',40,'部门40') 部门 from emp;

--3.得到工资大于自己部门平均工资的员工信息;
select s.*,e.empno,e.ename from 
   (select deptno,trunc(avg(sal)) avgsal from emp group by deptno) s,emp e 
where s.deptno=e.deptno and e.sal>s.avgsal;

select e.empno,e.ename from emp e 
where e.sal>
(select trunc(avg(sal)) avgsal from emp s 
where s.deptno=e.deptno group by deptno )

--4.列出所有员工的姓名和其上级的姓名;
select e.ename,m.ename from emp e,emp m where e.mgr=m.empno;

--5.得到每个月工资总数最少的那个部门的部门编号,部门名称,部门位置;
select s.*,d.* from 
  (select rownum rn,e.* from 
  (select deptno,sum(sal) sumsal from emp group by deptno order by sumsal) e) s,
 dept d
where s.rn=1 and s.deptno=d.deptno;

--6.查找出部门10和部门20中,工资最高第3名到工资第5名的员工的员工名字,
--  部门名字,部门位置;
select s.*,d.* from 
 (select e.*,row_number() over(partition by deptno order by sal ) rn
  from emp e where deptno in (10,20)) s,dept d
where s.rn between 3 and 5 and d.deptno=s.deptno;
-----------------------
select s.*,d.* from  dept d,
  (select * from 
  (select rownum rn,ename,sal,deptno from
   (select * from emp where deptno in(10,20) order by sal desc))
  where rn>=3 and rn<=5) s
where d.deptno=s.deptno

--7.查询出king所在部门的工作年限最大的员工名字;
select * from 
(select rownum rn,sysdate-hiredate sh,ename from emp where deptno=
    (select deptno from emp where ename='KING') order by sh desc) s
where s.rn=1
-----------
select * from
 (select hiredate,ename from emp where deptno=
  (select deptno from emp where ename='KING') order by hiredate)
where rownum=1;

--8.列出员工表中每个部门的员工数(员工数必须大于3),和部门名称;
select e.cou,d.* from dept d,
 (select deptno,count(*) cou from emp group by deptno having count(*)>3) e
where e.deptno=d.deptno;

--9.查询出各个员工的工资级别; salgrade
select ename,s.grade from emp,salgrade s 
 where sal between s.losal and s.hisal;

--10.给emp表添加字段dname,并根据部门信息更新该字段的内容;
alter table emp add (dname varchar2(20));
update emp e set dname = (select d.dname from dept d where e.deptno=d.deptno)
 where exists(select d.dname from dept d where e.deptno=d.deptno);
--where e.deotno in(select deptno form dept d)
--exists 存在即修改,不存在则不修改 
 
--二、根据要求创建表并进行相关操作
/*
1、按如下要求创建表 class 和 student,
              属性    类型(长度)  默认值  约束              注释
Class表     classno   数值(2)      无     主键            班级编号
            cname     变长字符(10) 无     非空            班级名称
student表   stuno     数值(8)      无     主键            学号
            sname     变长字符(12) 无     非空            姓名
            sex       字符(2)      男     无              性别
            birthday  日期           无     无              生日
            email     变长字符(20) 无     唯一            电子邮件
            score     数值(5,2)   无     检查(0<=成绩<=100)  成绩
            classno    数值(2)     无     外键 关联到表class的classno主键  班级
*/
create table class(
     classno   number (2)  ,                
     cname     varchar(10) not null
);
  alter table class add constraint c_pk primary by(classno);

create table student(
    stuno     number (8)   primary key,  
    sname     varchar2(12) not null ,
    sex       char(2)      default( '男' ),
    birthday  date         , 
    email     varchar2(20) unique,
    score     number(5,2)  ,
    classno    number(2)   
)

alter table class add constraint s_ck check(0<=score<=100);

--2.在表student的sname属性上创建索引student_index_id;
create index student_index_id on student(sname);

--3.创建序列stuseq,要求初始值为20050001,增量为1,最大值为20059999;
create sequence stuseq 
start with 20050001
increment by 1
maxvalue 20059999

/*4、向student中插入如下数据
   STUNO           SNAME SEX    BIRTHDAY    EMAIL      SCORE CLASSNO 
 从 stuseq 取值    tom   男    1995-2-3    [email protected]  89.50   1 
 从 stuseq 取值    jerry     默认值 空          空         88      2
从 stuseq 取值     alice   女    1994-2-5    [email protected]  空    3 */

select * from student
insert into student(SNAME,SCORE,CLASSNO) values('jerry',88,2);
insert into student(SNAME,SEX,BIRTHDAY,EMAIL,SCORE,CLASSNO) values('tom','男',to_date('1995-02-03','yyyy-mm-dd'),'[email protected]',89.50,1);        
insert into student(SNAME,SEX,BIRTHDAY,EMAIL ,CLASSNO) values('alice','女',to_date('1994-02-05','yyyy-mm-dd'),'[email protected]',3 );

--5.修改表 student 的数据,将所有一班的学生成绩加 10 分。
update student set score= score+10  where classno=1;

--6.删除表 student 的数据,将所有 3 班出生日期小于 1991 年 5 月 12 日
--的记录删除。
delete  from student where classno=3 and birthday>to_date('1991-05-12','YYYY-MM-DD');
--7.将以下数据加入到class表中
insert into class values(1,'一班');
insert into class  values(2,'二班');
insert into class  values(3,'三班');

insert into class  values(4,'四班');

-- 8.完成以下 SQL 语句。 
--(1) 按班级编号分组统计每个班的人数,
--最高分,最低分,平均分,并按 平均分降序排序
select count(classno),max(score),min(score),avg(score) 

   from student group by classno order by avg(score);

--(2)统计二班学生中所有成绩大于所有班级平均分的人数。 
select count(1) from student where stuno in
(select stuno from student where classno=2 and 

score>(select avg(score) from student));

--(3)查询平均分最高的班级编号与分数。
select classno,score from student where classno in(select classno from student group by classno

having avg(score)>=all(select avg(score) from student group by classno));

--(4)查询所有学生记录中成绩前十名的学生的学号、姓名、成绩、班级编号。 
select stuno,sname,score,classno from 

(select * from student s order by score desc) where rownum<=10;

--(5)创建视图 stuvu ,要求视图中包含 student 表中所有一班学生的
-- stuno, sname, score, classno 四个属性,  并具有 with read only 限制。
create or replace   noforce view stuvu as 
select stuno, sname, score, classno from student where  classno=1  with read only;

--三、(1)创建一张emp1的日志记录表,emp1_log,
--日志记录表的字段为emp1表的字段,
--并且在emp1表的字段基础上添加两个字段信息elogno (日志主键),
--execdesc(操作描述),操作时间(exectime)
--创建序列,用来生成日志表的主键信息
create table emp1_log as select * from emp1 where 1=2;
alter table emp1_log add(elogno number, execdesc varchar2(10), exectime date);
alter table emp1_log add constraint pk_emp1_log primary key(elogno);
create sequence seq_emp1_log ;

--(2)编写一个触发器在emp1表上,触发时机和触发事件为删除之后
--或者修改ename之后,触发类型为行级触发,
--内容为将删除的原数据和修改的原数据记录进emp1_log表中,
--并添加描述,即如果是修改操作的语句,
--则将描述内容记为'update',如果是删除语句的内容,则将描述内容记为'delete'。
--要求emp1_log表中有delete和update的数据,并且记录时间。

create or replace trigger tri_emp1 
after
delete or update of sname
on emp1 
for each row
begin
case
 when deleting then
  insert into emp1_log(ENO,ENAME,SEX,AGE,DEPTNO,ELOGNO,EXECDESC,EXECTIME)
  values(:old.ENO,:old.ENAME,:old.SEX,:old.AGE,:old.DEPTNO,seq_stu.nextval,
        'delete',sysdate);
 when updating('ename') then
  insert into emp1_log(ENO,ENAME,SEX,AGE,DEPTNO,ELOGNO,EXECDESC,EXECTIME)
  values(:old.ENO,:old.ENAME,:old.SEX,:old.AGE,:old.DEPTNO,seq_stu.nextval,
         'update',sysdate);
end case;
end;

猜你喜欢

转载自blog.csdn.net/qq_39870734/article/details/79529272