PLSQL Day5

-- 14.使用显式游标更新行,提升两个资格最老的员工为manager:
declare
  cursor e_cur is select * from emp order by hiredate desc for update;
begin
  for e in e_cur loop
    if e_cur%rowcount<3 then
      update emp set job = 'MANAGER' where empno = e.empno;
    end if;
  end loop;
end;

select * from emp order by hiredate desc
-- 15.使用显式游标更新行,对员工的薪水判断,如果高于所在部门的平均薪水,则薪水减50:
declare 
  cursor e_cur is select * from emp for update;
  avg_sal number;
begin
  for e in e_cur loop
    select avg(sal) into avg_sal from emp where deptno = e.deptno;
    dbms_output.put_line(e.ename||' '||avg_sal);
    if e.sal > avg_sal then
      update emp set sal = nvl(sal,0) - 50 where empno= e.empno;
    end if;
  end loop;
end;
select * from emp;
-- 6.使用隐式游标属性,修改员工号为7654的员工工资,将其工资增加500元。
-- 如果该员工不存在,则向员工表中插入一条员工号为7654的记录(其他列为空):
begin
  update emp set sal = sal + 500 where empno = 7654;
  if sql%notfound then
    dbms_output.put_line('Not Found!');
    insert into emp(empno) values(7654);
  end if;
end;
select * from emp;


--17.将名字中带有‘S’的员工删除,并使用隐式游标统计删除几人,还剩几人:
declare
  cnt number;
begin
  delete from emp where ename like '%S%';
  dbms_output.put_line('删除人数:'||sql%rowcount);
  select count(*) into cnt from emp;
  dbms_output.put_line('剩余人数:'||cnt);
end;
select * from emp;

--18.要求根据输入的不同表名进行不同处理,若输入的表名为emp,则显示高于10号部门平均工资的员工信息;
--若表名为 dept,则显示各个部门的人数。若输入其他表名,则直接提示‘请输入员工表或部门表!’:

-- REF游标
declare
  tb_name varchar2(50) := '&表名';
  type e_d_cur is ref cursor;
  cur e_d_cur;
  e emp%rowtype;
  type d_type is record(
    dno number,
    cnt number
  );
  d d_type;
begin
  if tb_name = 'emp' then
    open cur for select * from emp where sal > (select avg(sal) from emp where deptno = 10);
    loop 
      fetch cur into e;
      exit when cur%notfound;
      dbms_output.put_line(e.empno||' '||e.ename||' '||e.job
      ||' '||e.mgr||' '||to_char(e.hiredate,'yyyy-MM-dd')||
      ' '||e.sal||' '||e.comm||' '||e.deptno);
    end loop;
    close cur;
   elsif tb_name = 'dept' then
     open cur for select deptno,count(*) from emp group by deptno ;
     loop
       fetch cur into d;
       exit when cur%notfound;
       dbms_output.put_line(d.dno||'号部门人数: '||d.cnt);
     end loop;
     close cur;
   else
     dbms_output.put_line('请输入员工表或部门表!');
   end if;
end;

---- 显式游标
declare
  cursor e_cur is select * from emp where sal > (select avg(sal) from emp where deptno = 10);
  cursor d_cur is select deptno,count(*) cnt from emp group by deptno;
  tb_name varchar2(50) := '&部门号';
begin
  if tb_name = 'emp' then
    for e in e_cur loop
      dbms_output.put_line(e.empno||' '||e.ename||' '||e.job
      ||' '||e.mgr||' '||to_char(e.hiredate,'yyyy-MM-dd')||
      ' '||e.sal||' '||e.comm||' '||e.deptno);
    end loop;
  elsif tb_name = 'dept' then
    for d in d_cur loop
      dbms_output.put_line(d.deptno||'号部门人数: '||d.cnt);
    end loop;
  else
    dbms_output.put_line('请输入员工表或部门表!');
  end if;
end;


/*
create table c_staff(
staff_no varchar2(23),
staff_name varchar2(34),
staff_sex varchar2(34),
staff_age number,
come_date date,
group_name varchar2(34),
super_statff_no varchar2(43)
);

insert into c_staff values(34065,'杨志军','男',25,to_date(20130716,'yyyymmdd'),'交付运维部','于波');
insert into c_staff values(43533,'宋非凡','男',18,to_date(20201117,'yyyymmdd'),'交付运维部','杨志军');

create table c_check_record(
staff_no varchar2(12),
ymd varchar2(8),
is_come varchar2(12));

insert into c_check_record values(34065,20230201,'出勤');
insert into c_check_record values(34065,20230202,'出勤');
insert into c_check_record values(34065,20230203,'缺勤');
insert into c_check_record values(34065,20230204,'出勤');
insert into c_check_record values(34065,20230205,'出勤');

create table e_month_chek(
ym varchar2(16),
full_num number(8),
defect_num number(8),
full_rate number(8,2),
come_date number(8,2)
);*/
select * from c_staff;
select * from c_check_record;

-- 1、查询2021年一共入职了几名员工,平均年龄是多少(5分)。
select count(*) 人数,avg(staff_age) 平均年龄 from (select * from c_staff where extract(year from come_date) = '2021');
-- 2、查询于波管理的所有员工清单,包括下级和下下级员工,结果字段包括:员工编号、员工姓名、上级领导编号、上级领导姓名(15分)。
select b.staff_no,b.staff_name,a.staff_no,a.staff_name from
(select staff_no,staff_name from c_staff where staff_name = '于波' ) a
join
(select staff_no,staff_name,super_statff_no from c_staff
start with super_statff_no = '于波'
connect by prior super_statff_no = staff_name) b
on a.staff_name = b.staff_name;
-- 3、统计杨志军在2023年2月的出勤情况,即出勤几天,缺勤几天(10分)。
select sum(decode(is_come,'出勤',1,0)) 出勤,
sum(decode(is_come,'缺勤',1,0)) 缺勤 from
(select cs.staff_no,cs.staff_name,cc.ymd,cc.is_come from c_staff cs,c_check_record cc 
where cs.staff_name = '杨志军' and cs.staff_no = cc.staff_no and substr(cc.ymd,5,2) = '02');

-- 5、统计2023年2月所有人的出勤天数,并按照出勤天数从高到低进行排序,要求字段:员工姓名、所在部门、上级领导姓名、出勤天数(20分)。

select staff_no,staff_name,group_name,mgr_name,sum(decode(is_come,'出勤',1,0)) 出勤天数 from
(select c1.staff_no, c1.staff_name,c1.group_name,c2.staff_name mgr_name,cc.is_come from c_staff c1 left join c_staff c2 on c1.super_statff_no = c2.staff_name
 left join c_check_record cc on c1.staff_no = cc.staff_no where substr(cc.ymd,5,2) = '02')
 group by staff_no,staff_name,group_name,mgr_name order by sum(decode(is_come,'出勤',1,0));

-- 6、编写多个脚本实现以下统计结果:统计每个月全勤的人数、存在缺勤的人数、
-- 全勤率(全勤率=全勤人数/总人数)、环比变化(本月全勤率-上月全勤率)(30分)。
-- 将统计结果插入下表。
select * from e_month_chek
-- 每个人每个月份的出勤情况
insert into e_month_chek
select g.*,g.全勤cnt/e.c 全勤率,nvl((g.全勤cnt/e.c-lag(g.全勤cnt/e.c)over(order by g.month)),0) 环比 from(
with t as
(select cs.staff_no,cs.staff_name,substr(cc.ymd,1,6) month,
nvl(sum(decode(cc.is_come,'出勤',1,0)),0)出勤,
nvl(sum(decode(cc.is_come,'缺勤',1,0)),0)缺勤 
from c_staff cs 
left join c_check_record cc 
on cs.staff_no = cc.staff_no 
group by cs.staff_no,cs.staff_name,substr(cc.ymd,1,6))

-- 不同月份全勤的人数
/*
select staff_no,staff_name,month from t 
where t.缺勤 = 0 and t.出勤 != 0     -- 不同月份全勤的人的名单
*/
--select b.month,nvl(a.全勤cnt,0) 全勤cnt,b.缺勤cnt from
(select month,count(staff_name) 全勤cnt from t 
where t.缺勤 = 0 and t.出勤 != 0
group by month) a full join

-- 不同月份缺勤的人数
-- 不同月份缺勤的人的名单
/*select staff_no,staff_name,month from t 
where t.缺勤 != 0 */
 (select month,count(staff_name) 缺勤cnt from t 
 where t.缺勤 != 0
group by month) b
on a.month = b.month) g,
(select count(*) c from c_staff) e
-- 公司总人数
/*select count(*) from c_staff;*/

----------------------------------------------------QTingLJQ-------------------------------------------------------------------
--insert into e_month_chek
select mon,全勤人数,缺勤人数,全勤人数/n 全勤率,全勤人数/n-nvl(lag(全勤人数/n)over(order by mon),0) 环比变化 from
(select mon,sum(b) 全勤人数,sum(c) 缺勤人数 from 
(select staff_no,mon,a,case when a=m then 1 else 0 end b,
case when a<m then 1 else 0 end c from -- 出勤a<m 说明没有全勤、如果a=m,说明全勤
(select staff_no,mon,sum(decode(is_come,'出勤',1,0)) a,
substr(to_char(last_day(to_date(mon,'yyyy-mm')),'yyyymmdd'),7,2) m -- 找到当前月的最后一天
from 
(select staff_no,substr(ymd,1,6) mon,is_come from c_check_record) -- 截取时间到月
group by staff_no,mon)) 
group by mon),(select count(*) n from c_staff)

select* from e_month_chek

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值