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 T1.TRANS_TIME=@输入日期) 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 T1.TRANS_TIME=@输入日期) T2
WHERE T2.TRANS_NO=@输入的流水号
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;
第四大题
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;