Oracle数据库上机练习5

Oracle上机练习题(五)

试卷总分:120

答题时间:240分钟

 

第一大题

create table ODM.T_ACCT        ---账户表

(ACCT_ID    varchar2(19)    ---账户号 PK

,ACCT_TYPE    varchar2(2)    ---账户性质 01活期;02定期;03保证金

,BAL        number(24,6)    ---余额

);

create table ODM.T_ACCT_CUST    ---账号所属客户表

(ACCT_ID    varchar2(19)    ---账户号 PK

,CUST_ID    varchar2(9)    ---所属客户号,同一客户可能有多个同一账户性质的账户

);

create table ODM.T_ACCT_INFO    ---账号基本信息表

(ACCT_ID    varchar2(19)    ---账户号 PK

,OPEN_BRANCH    varchar2(6)    ---开户机构

,OPEN_DATE    date        ---开户日期

,ACCT_STS    varchar2(2)    ---账号状态 01正常;02注销;03冻结

);

create table ODM.T_CUST_INFO    ---客户基本信息表

(CUST_ID    varchar2(9)    ---客户号 PK

,CUST_NAME    varchar2(20)    ---客户姓名

,CUST_NBR    varchar2(18)    ---证件号,同一客户可能通过相同证件号注册多个客户号

,NBR_TYPE    varchar2(2)    ---证件类型

,CUST_TEL    varchar2(13)    ---手机号码

,OPEN_BRANCE    varchar2(6)    ---开户机构

,OPEN_DATE    date        ---开户日期

);

create table ODM.T_TRANS_INFO    ---交易流水表

(ACCT_ID    varchar2(19)    ---交易账户号

,TRANS_NO    varchar2(20)    ---交易流水号

,TRANS_TIME    date        ---交易日期时间

,TRANS_BAL    numeric(24,6)    ---交易金额

,OPP_ACCT_ID    varchar2(19)    ---交易对手账户号

);

1.

统计2个指标:1)机构号 PK 2)活期总余额小于5万且定期总余额小于10万的客户数。
补充说明:
1)    证件号+证件类型相同的为同一个客户,所属机构取【客户基本信息表】中开户日期小的客户号的开户机构。
2)    余额只取账号状态为正常的。[5分]

SELECT T.OPN_BRANCH,COUNT(DISTINCT T.CUST_NBR||T.NBR_TYPE)AS NUM FROM 
 (SELECT T3.OPN_BRANCH,T3.CUST_NBR,T3.NBR_TYPE 
 FROM ODM.T_ACCT T1,ODM.T_ACCT_INFO T3,ODM.TACCT_INFO T5
 WHERE T1.ACCT_ID=T2.ACCT_ID AND T2.CUST_ID=T3.CUST_ID AND T3.OPN_DATE=
 (SELECT MIN(T4.OPN_DATE) FROM ODM.T_CUST_INFO T4 
 WHERE T3.CUST_NBR=T4.CUST_NBR AND T3.NBR_TYPE=T4.NBR_TYPE)
 AND T1.ACCT_ID=T5.ACC_ID AND T5.ACCT_STS='01' AND T1.ACCT_TYPE='01'
 GROUP BY T3.OPN_BTANCH,T2.CUST_NBR,T3.NBR_TYPE
 HAVING SUM(T1.BAL)<50000 --总余额小于5万的
 INTERSECT
 SELECT T3.OPN_BRANCH,T3.CUST_NBR,T3.NBR_TYPE 
 FROM ODM.T_ACCT T1,ODM.T_ACCT_CUST T2,ODM.T_CUST_INFO T3,ODM.T_ACCT_INFO T5
 WHERE T1.ACCT_ID=T2.ACCT_ID
 AND T2.CUST_ID=T3.CUST_ID AND T3.OPN_DATE=
 (SELECT MIN(T4.OPN_DATE) FROM ODM.T_CUST_INFO T4
 WHERE T3.CUST_NBR=T4.CUST_NBR
 AND T3.NBR_TYPE=T4.NBR_TYPE)
 AND T1.ACCT_ID=T5.ACC_ID AND T5.ACCT_SYS='01' AND T1.ACCT_TYPE='02'
 GROUP BY T3.OPN_BRANCH,T3.CUST_NBR,T3.NBR_TYPE
 HAVING SUM(T1.BAL)<100000) T
 GROUP BY T.OPN_BRANCH;

2.

统计1个指标:1)账户号 限定为近30田李在连续的2天内交易次数大于等于10次或交易总金额大于等于100万的账号。[5分]

SELECT ACCT_ID FROM
 (SELECT T2.ACCT_ID,T2.NUM+T3.NUM AS TOTAL_NUM,T2.BAL+T3.BAL AS TOTAL_BAL
 FROM (SELECT T1.TRANS_TIME,T1.ACCT_ID,
 COUNT(DISTINCT T1.TRANS_NO) AS NUM,SUM(T1.TRANS_BAL) AS BAL
 FROM ODM.T_TRACE_INFO T1
 WHERE T1.TRANS_TIME>=SYSDATE-30
 AND T1.TRANS_TIME<=SYSDATE
 GROUP BY T1.TRANS_TIME,T1.ACCT)ID) T2,
 (SELECT T1.TRANS_TIME,T1.ACCT_ID,
 COUNT(DISTINCT T1.TRANS_NO) AS NUM,SUM(T1.TRANS_BAL) AS BAL
 FROM ODM.T_TRANCE_INFO T1
 WHERE T1.TRANS_TIME>=SYSDATE-30
 AND T1.TRANS_TIME<=SYSDATE
 GROUP BY T1.TRANS_TIME,T1.ACCT_ID) T3
 WHERE T2.TRANS_TIME=T3.TRANS_TIME+1
 AND T2.ACCT_ID=T3.ACCT_ID) T
 WHERE T.TOTAL_NUM>=10 OR T.TOTAL_BAL>-1000000;

 

第二大题

create table ODMT_CARD        ---卡片信息表

(CARD_NBR    varchar2(19)    ---卡号 PK

,ACCT_ID    varchar2(19)    ---所属账户号

,ISSUE_DAY    date        ---发卡日期

,ACTIVE_DAY    date        ---**日期,未**得为空值

,ISSUE_BRANCH    varchar2(6)    ---发卡机构

);

create table ODMT_EXC_CARD    ---换卡信息表

(CARD_NBR    varchar2(19)    ---卡号 PK

,CARD_NBR_BF    varchar2(19)    ---换卡前对应卡号

,EXC_DAY    date        ---换卡日期

);

1.

按机构号统计近三个月以来每个月得发卡数量,共4个指标:1)机构号 PK  2)上月发卡数量 3)上上月发卡数量 4)前第3个月发卡数量。
补充说明:
1)只统计首长卡且**了的卡片,换卡的不纳入发卡数量的统计范围。
2)注释清晰、有条理、便于维护占15分,无任何注释0分。[5分]

SELECT T1.ISSUE_BRANCH ,T1.NUM AS '上个月发卡数',T2.NUM AS '上上个月发卡数'

       ,T3.NUM AS '前第3个月发卡数' 

       FROM 

       (SELECT T1.ISSUE_BRANCH ,TO_CHAR(T1.ISSUE_DAY,'YYYY-MM') AS MONTH,

       COUNT(DISTINCT T1.CARD_NBR) AS NUM FROM ODM.T_CARD T1 

       WHERE T1.ISSUE_DAY >= TRUNC(ADD_MONTHS(SYSDATE, -1))  --上个月月初

       AND T1.ISSUE_DAY <= LAST_DAY(ADD_MONTHS(SYSDATE, -1))  --上个月月末

       AND T1.ACTIVE_DAY IS NOT NULL  --**日期不为空

       AND NOT EXISTS (SELECT 1 FROM ODM.T_EXC_CARD T2  --剔除换卡的卡片

                                           WHERE T1.CARD_NBR = T2.CARD_NBR )

       GROUP BY T1.ISSUE_BRANCH ,TO_CHAR(T1.ISSUE_DAY,'YYYY-MM')) T1   --上个月的发卡统计

       ,

       (SELECT T1.ISSUE_BRANCH ,TO_CHAR(T1.ISSUE_DAY,'YYYY-MM') AS MONTH,

       COUNT(DISTINCT T1.CARD_NBR) AS NUM FROM ODM.T_CARD T1 

       WHERE T1.ISSUE_DAY >= TRUNC(ADD_MONTHS(SYSDATE, -2))  --上上个月月初

       AND T1.ISSUE_DAY <= LAST_DAY(ADD_MONTHS(SYSDATE, -2))  --上上个月月末     

       AND T1.ACTIVE_DAY IS NOT NULL  --**日期不为空

       AND NOT EXISTS (SELECT 1 FROM ODM.T_EXC_CARD T2  --剔除换卡的卡片

                                           WHERE T1.CARD_NBR = T2.CARD_NBR )

       GROUP BY T1.ISSUE_BRANCH ,TO_CHAR(T1.ISSUE_DAY,'YYYY-MM')) T2  --上上个月的发卡统计

       ,

       (SELECT T1.ISSUE_BRANCH ,TO_CHAR(T1.ISSUE_DAY,'YYYY-MM') AS MONTH,

       COUNT(DISTINCT T1.CARD_NBR) AS NUM FROM ODM.T_CARD T1 

       WHERE T1.ISSUE_DAY >= TRUNC(ADD_MONTHS(SYSDATE, -3))  --前第3月月初

       AND T1.ISSUE_DAY <= LAST_DAY(ADD_MONTHS(SYSDATE, -3))  --前第3月月末     

       AND T1.ACTIVE_DAY IS NOT NULL  --**日期不为空

       AND NOT EXISTS (SELECT 1 FROM ODM.T_EXC_CARD T2  --剔除换卡的卡片

                                           WHERE T1.CARD_NBR = T2.CARD_NBR )

       GROUP BY T1.ISSUE_BRANCH ,TO_CHAR(T1.ISSUE_DAY,'YYYY-MM')) T3   --前第3个月的发卡统计

       WHERE T1.ISSUE_BRANCH = T2.ISSUE_BRANCH  --发卡机构关联

       AND  T2.ISSUE_BRANCH = T3.ISSUE_BRANCH  --发卡机构关联

 

第三大题

create table ODM.T_ACCT        ---账号表

(ACCT_ID        varchar2(19)    ---账户号 PK

,ACCT_TYPE      varchar2(2)    ---账户性质 01 活期;02 定期;03 保证金

,BAL            numeric(24,6)  ---余额

);

create table ODM.T_ACCT_INFO    ---账户基本信息表

(ACCT_ID        varchar2(19)    ---账户号 PK

,OPEN_BRANCH    varchar2(6)    ---开户机构

,OPEN_DATE      date            ---开户日期

,ACCT_STS      varchar2(2)    ---账号状态 01 正常;02 注销;03 冻结

);

create table ODM.T_TRANS_INFO  ---交易流水表

(ACCT_ID        varchar2(19)    ---交易账户号

,TRANS_NO      varchar2(20)    ---交易流水号

,TRANS_TIME    date            ---交易日期时间

,TRANS_BAL      numeric(24,6)  ---交易金额

,OPP_ACCT_ID    varchar2(19)    ---交易对手账户号

);

1.

一条SQL展示5个指标:1)账户号 PK 2)开户机构 3)账户性质 4)余额 5)同一开户机构下同一账户性质的所有账户的平均余额,其中所有账户都限定为正常装填的。
 [5分]

SELECT T1.ACCT_ID,T2.OPN_BRANCH,T1.ACCT_TYPE,T1.BAL,T5.AVG_BAL
 FROM ODM.T_ACCT T1,ODM.T_ACCT_INFO T2,
 (SELECT T4.OPN_BRANCH,T1.ACCT_TYPE,AVG(T3.BAL) AS AVG_BAL
 FROM ODM.T_ACCT T3,ODM.T_ACCT_INFO T4
 WHERE T3.ACCT_ID=T4.ACCT_ID
 AND T4.ACCT_STS='01'
 GROUP BY T4.OPN_BRANCH,T3.ACCT_TYPE) T5
 WHERE T1.ACCT_ID=T2.ACCT_ID
 AND T2.OPON_BRANCH=T5.OPN_BRANCH
 AND T1.ACCT_TYPE=T5.ACCT_TYPE;

2.

根据输入的交易日期时间和交易流水号,展示3个指标:1)交易账户号 2)交易金额 3)同一交易账户下前2笔交易、当前笔交易、下2笔交易共连续5笔的平均交易金额。[5分]

SELECT T1.ACCT_ID,T2.TRANS_BAL,AVG(T1.TANS_SAL)
 (SELECT T1.ACCT_ID,T1.TRANS_BAL,T1.TRANS_NO,
 ROW_NUMBER() OVER(PARTITION BY T1.TRANS_TIME,T1.ACCT_ID 
 ORDER BY T1.TRANS_NO ASC) AS CN
 FROM ODM_TRANS_INFO T1
 WHERE [email protected]输入日期) T1,
 (SELECT T1.ACCT_ID,T1.TRANS_BAL,T1.TRANS_NO,
 ROW_NUMBER() OVER(PARTITION BY T1.TRANS_TIME,T1.ACCT_ID 
 ORDER BY T1.TRANS_NO ASC) AS CN
 FROM ODM_TRANS_INFO T1
 WHERE [email protected]输入日期) T2
 WHERE [email protected]输入的流水号
 AND T2.ACCT_ID=T1.ACCT_ID
 AND T1.CN>=T2.CN-2
 AND T1.CN<=T2.CN+2
 GROUP BY T1.ACCT_ID,T2.TRANS_BAL
 HAVING COUNT(T1.TRANS_NO)=5;

第四大题

 Oracle数据库上机练习5 

1.

查询每个人的主管(主管本人不包含在内)。[5分]

select t1.*,t2.manager from employee t1,dept t2
 where t1.dept=t2.deptno
 and not exists(select t1 from dept t3 where t1.empno=t3.manager);

2.

查询每个部门的男女总人数,其中性别(0-男,1-女)现实为M-男,F-女。如下:
男    3
女    5[5分]

select deptno,case when sex=0 then 'M-男' when sex=1 then 'F-女' end,num
 from (select t1.deptno,t2.sex,count(*) as num 
 from dept t1 left join employee t2 on t1.deptno=t2.dept
 group by t1.deptno,t2.sex);

3.

查询每个部门的平均年龄。[5分]

select t1.deptno,avg(nvl(t2.age,0) as num
 from dept t1 left join employee t2 on t1.deptno=t2.dept
 group by t1.deptno;

4.

查询每个部门工资最低的员工。[5分]

select t1.deptno,min(t3.money)
 from dept t1 left join employee t2 on t1.deptno=t2.dept left join wage t3 on t2.empno=t3.empno 
 and t3.item='salery'
 group by t1.deptno;

5.

查询每个部门工资最高的前三名,升序排列。[5分]

select t.* from
 (select t1.deptno,t3.*,row_number() over(partition by t1.deptno 
 order by t3.money desc) as num
 from dept t1 left join employee t2 on t1.deptno=t2.dept left join wage t3 on t2.empno=t3.empno and t3.item='salery') t
 where t.num<=3
 order by t.deptno,t.num desc;

6.

查询工资延迟结算的人(结算日期大于次月1号)。[5分]

select distinct t.empno wage t where t.item='Late'
 and t.countDate>add_month(to_date(t.month||'01','yyyy-mm-dd'),1);

7.

将所有主管的奖金(Bonus)修改为450。[5分]

update wage set item=450 where item='Bonus' and empno in
 (select manager from dept);

8.

将2005年至2018年所有的月份输出,包括月份、月初日期、月末日期。
例如:201801,20180101,20180131。[5分]

select day_id,day_id||'01',last_day(to_date(day_id||'01','yyyy-mm-dd'))
 from
 (select to_char(add_months(to_date('2005-01','yyyy-mm'),rownum-1),'yyyy-mm') day_id
 from dual
 connect by rownum<=months_between
 (to_date('2005-01','yyyy-mm'),to_date('2018-12','yyyy-mm'))+1);

第五大题

1.

创建一个口令认证的数据库用户usera_exer,口令为usera,默认表空间为USERS,配额为10MB,初始账号为锁定状态。[5分]

create user usera_exer identified by usera default tablespace users quota 10m on users account lock;

2.

创建一个口令认证的数据库用户userb_exer,口令为userb。[5分]

create user userb_exer identified by userb;

3.

为usera用户授予CREATE SESSION权限、scott.emp表的SELECT权限和UPDATE权限。同时允许该用户将获得的权限授予其他用户。[5分]

grant select,update on scott.emp to usera_exer;
grant create session to usera_exer;
grant dba to usera_exer;

4.

将用户usera_exer的账号解锁。[5分]

alter user usera_exer account unlock;

5.

用usera_exer登录数据库,查询和更新scott.emp中的数据。同时,将scott.emp的SELECT和UPDATE权限授予用户userb_exer。[5分]

conn usera_exer;
select * from scott.emp;
update scott.emp set sal=2333 where empno=7654;
grant select,update on scott.emp to userb_exer;

6.

禁止用户usera_exer将获得的CREATE SESSION权限再授予其他用户。[5分]

revoke create session from usera_exer;

7.

禁止用户usera_exer将获得的scott.emp的SELECT权限和UPDATE权限再授予其他用户。[5分]

revoke select,update on scott.emp from usera_exer;

8.

创建角色rolea和roleb,将CREATE TABLE权限,scott.emp的INSERT权限和DELETE权限授予rolea;将CONNECT,RESOURCE角色授予roleb。[5分]

create role rolea;
create role roleb;
grant insert,delete on scott.emp to rolea;
grant create table to rolea;
grant connect,resource to roleb;

9.

将角色rolea,roleb授予用户usera_exer。[5分]

grant rolea,roleb to usera_exer;

10.

屏蔽用户user_exer的roleb角色。[5分]

revoke roleb from user_exer;

11.

为用户usera_exer创建一个概要文件,限定该用户的最长会话时间为30分钟,如果连接10分钟空闲,则结束会话。同时,限定其口令有效期为20天,连续登录4次失败后将锁定该账号,10天后自动解锁。[5分]

create profile fwj_frofile limit CONNECT_TIME 30 IDLE_TIME 10 PASSWORD_LIFE_TIME 20 FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME 10;
alter user usera_exer profile fwj_frofile;
alter user users profile special_user;