1 作业
2 Oracle基本操作练习题
3 Scotte用户下的两张数据表描述:
4 员工表(emp):
5 (
6 empno NUMBER(4)notnull, --员工编号,表示唯一
7 ename VARCHAR2(10), --员工姓名
8 job VARCHAR2(9), --员工工作职位
9 mgr NUMBER(4), --员工上级领导编号
10 hiredate DATE, --员工入职日期
11 sal NUMBER(7,2), --员工薪水
12 comm NUMBER(7,2), --员工奖金
13 deptno NUMBER(2) --员工部门编号
14 ) ;
15
16 部门表(dept):
17 (
18 deptno NUMBER(2)notnull, --部门编号
19 dname VARCHAR2(14), --部门名称
20 loc VARCHAR2(13) --部门地址
21 );
22
23
24 一、表的查询[所有小数都保留1位有效数字]
25 1.查询出emp表中总工资大于2500的员工姓名,基本工资,奖金,总工资
26 select ename,sal+nvl(comm,0) as sal from emp where sal>2500
27
28
29 2.请查询出emp表中姓名长度超过4位并且姓名中包含m或M字符的员工信息。
30 select * from emp where ename like '%M%' and length(ename)>4
31
32 3.请查询出emp表中最高级别领导的姓名。
33 select ename from emp where MGR is null;
34
35 4.请查询出emp表中所有领导的姓名。
36 select ename from emp where empno in (select mgr from emp group by mgr);
37
38 5.请查询出emp表中同SCOTT一年入职的员工信息
39 select * from emp where extract(year from hiredate)=(select extract(year from hiredate) from emp where ename='SCOTT')
40
41
42 6.请查询出所有12月份入职的员工信息
43 select * from emp where extract(month from hiredate)=12
44
45
46 7.请查询出emp中姓名后2个字符是ES的员工信息
47 select * from emp where ename like '%ES';
48
49 8.请查询出所有1981入职员工的总工资,平均工资,人数
50 select substr(hiredate,8,9) from emp;
51
52 select sum(sal+nvl(comm,0)) 总工资,avg(sal+nvl(comm,0)) 平均工资,count(*) 总人数 from emp
53 where substr(hiredate,8,9)=81;
54 9.请查询出不同年份入职员工的总工资,平均工资,人数和年份[只显示年]
55 select sum(sal),avg(sal),count(*),extract(year from hiredate) from emp group by extract(year from hiredate)
56 10.请查询出各部门总工资,平均工资,部门名称,并在部门内部排序,给出名次
57 select deptno,sum(sal*12+nvl(comm,0))总工资,round(avg(sal*12+nvl(comm,0)))平均工资,row_number() over(order by (round(avg(sal*12+nvl(comm,0)))) desc)from emp group by deptno;
58 11.请查询出emp表中所有员工姓名,总工资,部门名称
59 select ename,sal*12+nvl(comm,0),dname from emp,dept;
60
61 12.请查询出emp中各部门员工的总人数,总工资,平均工资,并根据平均工资倒序
62 select deptno as 部门名称,
63 count(*) as 总人数,
64 sum(sal+nvl(comm,0)) as 总工资,
65 avg(sal+nvl(comm,0)) as 平均工资
66 from emp group by deptno order by avg(sal+nvl(comm,0)) desc;
67
68 select * from emp;
69 13.请查询出各个部门员工的总人数,平均工资,部门名称
70 select d.dname 部门名称,count(*) 总人数,avg(e.sal+nvl(comm,0)) 平均工资 from emp e,dept d
71 where d.deptno=e.deptno
72 group by d.dname
73
74 14.请查询出各部门的名称,最高工资,最低工资,平均工资,并且平均工资保留1位有效数字,最后按照平均工资倒序
75 select DNAME as 部门名称,max(SAL) as 最高工资, min(SAL)as 最低工资,round(avg(SAL),1) as 平均工资 from emp e left join dept d
76 on e.deptno = d.deptno
77 group by DNAME
78 order by avg(SAL) desc;
79
80 15.请查询出部门名称为SALES的所有员工信息
81 select * from dept
82 select * from emp
83 select empno,ename,job,mgr,hiredate,round(sal,1),round(comm,1),deptno from emp where deptno=(select deptno from dept where dname='SALES')
84 16.请查询出没有员工的部门名称
85 select dname from dept where deptno not in (select deptno from emp group by deptno)
86
87 17.请查询出1981年入职人数超过2人的部门名称,入职人数
88 select dname 部门名称,count(*) from emp,dept
89 where emp.deptno=dept.deptno and extract(year from hiredate)=1981
90 group by dname
91 having count(*)>2
92
93
94 18.请查询出各部门工资最高的2个人信息,部门名称及工资
95 select 姓名,部门名称,工资 from
96 (
97 select
98 ename as 姓名,
99 dname as 部门名称,
100 sal+nvl(comm,0) as 工资,
101 row_number() over(partition by dname order by sal+nvl(comm,0) desc) as 排名
102 from emp e left join dept d
103 on e.deptno=d.deptno
104 )where 排名<=2
105 19.请查询出同一个岗位有2个人以上工资在1000以上的岗位名称和人数
106 select *from emp ;
107 select job,count(*) 人数 from emp where sal>1000
108 group by job
109 having count(*)>2
110
111
112
113 20.请查询与SCOTT在同一个部门的所有员工姓名,部门名称和岗位信息
114 select e.ename as 员工姓名,d.dname as 部门名称,e.job as 岗位信息 from dept d left join emp e on d.deptno=e.deptno
115 where d.dname=(select d.dname from dept d left join emp e on d.deptno=e.deptno where e.ename='SCOTT')
116
117
118 二、函数的熟练使用
119 1.查询出当前日期,当前时间
120 SELECT SYSDATE FROM DUAL ;
121 2.将当前日期转换为制定格式,如:2014-11-15 15:30
122 SELECT to_char(sysdate,'yyyy-mm-dd') from dual
123 3.分别取出当前日期的年,月,日
124 select substr(to_char(sysdate,'yyyymmdd'),0,4),substr(to_char(sysdate,'yyyymmdd'),5,2),substr(to_char(sysdate,'yyyymmdd'),7,2) from dual
125
126 4.请计算出字符串'hello world!'的长度
127 select length('hello world!') from dual;
128
129 5.请截取出字符串'hello world!'中的'world'字符串
130 select substr('hello world!',7,5) from dual;
131
132 6.请判断字符串'hello world!'中是否包含l字符
133 select count(*) as 一为包含零为不包含 from dual
134 where instr('hello world!','l') between 1 and length('hello world!');
135
136 select count(*) as 一为包含零为不包含 from dual
137 where 'hello world!' like '%l%';
138 7.请判断字符串'hello world!'中是不是只包含一个l字符
139 select instr('hello world!','l'),instr('hello world!','l',-1) from dual ;
140
141 8.请去掉' hello world! '左边的空格
142 select ltrim('hello world!') from dual;
143
144 9.请将字符串'hello World'中字符l替换为L
145 select replace('hello world','l','L')from dual;
146 10.将字符串152.568转换为数字并保留5位有效数字,其中2位是小数
147 select to_char('152.568','99G999D99') from dual
148
149 三、
150 1.找出部门10中所有经理、部门20中所有办事员以及既不是经理又不是办事员但其薪金大于或等于2000的所有雇员的详细资料
151 select * from emp where (deptno=10 and job='MANAGER') or (deptno=20 and job='CLERK') or (job<>'MANAGER'and job<>'CLERK'and sal>=2000);
152 2.找出收取佣金的雇员的不同工作
153 select distinct JOB from emp where comm>=0
154
155
156 3.显示雇员姓名,根据其服务年限,将最老的雇员排在最前面。
157 select ename 雇员名称,hiredate 入职时间,to_char(hiredate,'yyyy') 服务年限 from emp order by hiredate asc
158 4.显示在一个月为30天的情况下所有雇员的日薪金,忽略余数
159 select ename,sal+nvl(comm,0) 日薪金 from emp;
160
161 5.以年、月和日显示所有雇员的服务年限
162 select to_date(to_char(sysdate,'yyyy-mm-dd'),'yyyy-mm-dd')-to_date(to_char(hiredate,'yyyy-mm-dd'), 'yyyy-mm-dd') 入职天数,trunc(months_between(sysdate,hiredate)) 入职月份,to_char(sysdate,'yyyy')-to_char(hiredate,'yyyy') 入职年份 from emp
163
164 6.列出薪金高于在部门30工作的所有雇员的姓名和薪金
165 select * from emp
166 where sal>(
167 select max(sal) from emp where deptno=30
168 )
169
170 7.列出各种类别工作的最低工资
171 select job as 工作类型,min(sal) as 最低工资 from emp group by job ;
172 8.列出薪金水平处于第四位的雇员信息
173 select * from (select emp.*,rank() over (order by sal desc) i from emp )where i = 4
174 9.显示所有雇员的姓名以及满10年服务年限的日期
175 select ename,hiredate,add_months(hiredate,12*10) from emp
176 10.找出奖金高于薪金60%的雇员
177 select * from emp where comm>(sal * 0.6);
178
179 四、
180 1.查询出emp表中总工资大于2500的员工姓名,基本工资,奖金,总工资。
181 select ename 员工姓名,sal 基本工资,nvl(comm,0) 奖金,sal+nvl(comm,0) 总工资 from emp where (sal+nvl(comm,0))>2500
182
183 select * from emp
184 2.请查询出各个部门员工的总人数,平均工资,部门名称
185 select dname 部门名称,count(*) 总人数,nvl(avg(sal),0) 平均工资 from dept t left outer join emp e on t.deptno=e.deptno group by e.deptno,dname
186
187 3.根据当前时间日期,查询前天是什么时间
188 select to_char(sysdate-2,'yyy-mm-dd hh:mi:ss') from dual ;
189 4.分别取出当前日期的年,月,日
190 select to_char(sysdate,'yyyy') 年,to_char(sysdate,'mm') 月,to_char(sysdate,'dd') 日 from dual;
191
192 5.请将编号为7499的员工工资调整为2600元
193 select * from emp
194 select empno as 编号,sal as 工资 from emp where empno='7499'
195 update emp set sal='2600' where empno='7499'
196
197
198 6.创建一个新表为emp,里面有编号,姓名,待遇,入职时间,并以员工的姓名,待遇,然后用"姓名:xxx,待遇:xxx"格式显示
199 create table emp1
200 as
201 select empno,ename,hiredate,sal from emp;
202 select '编号:'||empno 编号,'姓名:'||ename 姓名,'入职时间:'||hiredate 入职时间,'待遇:'||sal 待遇 from emp1;
203
204
205 7.根据上一题的emp,获取第二个员工的姓名长度
206 select ename,length(ename) 长度,rn 序号 from(
207 select ename,row_number() over(order by empno)rn from emp1
208
209 )where rn=2
210
211 8.根据6题的emp表,查询出所有员工姓名,待遇并显示,但是待遇用#隐藏
212 select ename 姓名,replace(sal,sal,'#') 待遇 from emp1;
213
214 9.根据6题的emp表,--查询出第一个员工和第二个员工相隔多少天入职
215
216
217 10.根据6题的emp表,请根据工资待遇排序,然后查询出排名基数位的员工信息
218 select * from
219 (select ename as 姓名,sal as 待遇,row_number() over (order by sal desc) as rn from emp)
220 where mod(rn,2)=1;
221
222 五、
223 1.找出奖金高于薪水60%的员工信息。
224 select * from emp
225 where nvl(comm,0)>sal*0.6;
226
227 2.找出部门10中的职位为(MANAGER)和部门20中所有职位为(CLERK)的详细资料。
228 select * from emp e,dept t where e.deptno=t.deptno and
229 ((e.deptno=10 and job='MANAGER') or (e.deptno=20 and job='CLERK'));
230
231 3.统计各部门的薪水总和。
232 select dname,sum(sal) from emp e left outer join dept t on e.deptno=t.deptno group by dname;
233 select deptno,sum(sal) from emp group by deptno;
234 select * from emp;
235 4.找出部门10中的职位为(MANAGER),部门20中所职位为(CLERK)以及职位不是(MANAGER)但其薪水大于或等2000的所有员工的详细资料。
236
237 5.列出各种工作的最低工资。
238
239 6.列出各个部门的职位为(MANAGER)的最低薪水。
240
241 7.找出没奖金或奖金低于300的员工。
242
243 8.显示所有员工的姓名,首字母大写。
244
245 9.显示正好为5个字符的员工的姓名。
246
247 10.显示不带有“R”的员工姓名。
248
249 六、
250 1、请查询出dept表中每个部门的编号,员工总人数,最高工资,最低工资,总工资和平均工资,并按照部门编号倒叙排序。
251
252 2、请查询出dept表中每个部门的编号,每个部门的总年薪(包括奖金)以及每个部门的平均年薪。
253
254 3、请查询出每个部门的编号和各个部门员工的平均工作年限。
255
256 4、请查询出员工受雇日期早于自身上级领导的所有员工的编号,姓名,上级姓名和部门名称。
257
258 5、请查询出最低工资大于1500的各种工种以及从事此工资的全部员工人数。
259
260 6、请查询出部门名称为“SALES”的员工的姓名、工资,并按照雇佣日期的先后进行排序。
261
262 7、请查询出基本工资高于平均工资的所有员工姓名,员工工作,上级领导姓名,所在部门地址信息。
263
264 8、查询出每个雇员所在月倒数第二天被雇佣的雇员信息。
265
266 9、查询出所有已经被雇佣了35年以上的员工信息。
267
268 10、统计出emp表中共有多少个职位。
269
270 七、
271 1、请查询出emp表中第1-3条员工的信息
272
273 2、请查询出工资待遇在2000以上的员工姓名,工资
274
275 3、显示姓名正好为5个长度的所有员工
276
277 4、显示带有'R'的员工的详细
278
279 5、显示员工姓名的前三个字符
280
281 6、显示所有员工的姓名,用‘a’替换所有的'A'
282
283 7、显示一个月为30天的情况下,所有员工的日薪,忽略余数
284
285 8、请查询出工资待遇大于平均工资的员工信息
286
287 9、显示所有员工的姓名、工作和薪金,按工作的降序排列,工作相同则按照薪金的升序排列
288
289 10、显示一个月为30天的情况下,所有员工的日薪,忽略余数
290
291 八、
292 1、请查询出各部门的平均工资
293
294 2、请查询出各部门的总人数
295
296 3、请查询出各部门工资最高的员工信息
297
298 4、请查询出所有员工的姓名和总工资(基本工资+奖金)
299
300 5、请查询出所有员工的姓名以及至今入职了多少个月,并按倒序排序
301
302 6、请查询出姓名含有“T”的员工信息
303
304 7、请查询出姓名以“T”结尾的员工信息
305
306 8、请查询出工资最高的前三名员工,并按倒序排序
307
308 9、请查询出工资高于平均工资的所有员工信息
309
310 10、请按部门编号查询出所有员工信息,并显示偶数位的员工信息
311
312 九、
313 1、查询出emp表中的员工姓名,基本工资,奖金,总工资并按总工资从高到低排序。
314
315 2、查询出emp表中的员工比平均工资要高的基本信息
316
317 3、查询出emp表中1981年进来公司的员工基本信息
318
319 4、查询出emp表中姓名后1个字符是S的员工信息
320
321 5、查询出emp表中没有奖金的员工的姓名和基本工资
322
323 6、查询出emp表中在RESEARCH部门担任CLERK这职务的员工信息
324
325 7、查询出emp中员工编号7369的员工部门中的所有员工姓名,部门名称和岗位信息
326
327 8、查询出emp中工资排在第3到第6的员工信息。
328
329 9、查询出人数最多的部门名称和平均工资。
330
331 10、请查询出emp表中同SCOTT一年入职的员工信息及所在部门。
332
333
334 十、创建以下数据表,并按要求完成以下题目。
335 --班级表(编号,名称)
336 create table cls(
337 cno number primary key,
338 cname varchar2(20)
339 ) ;
340
341 --老师表(编号,姓名,性别,班级编号)
342 create table teacher(
343 tno number primary key,
344 tname varchar2(20),
345 tsex char(2) default '男' check(tsex='男' or tsex='女'),
346 tcno number,
347 foreign key(tcno) references cls(cno)
348 )
349 --学生表(编号,姓名,性别,年龄,入学时间,地址,在读状态,班级编号)
350 create table stu(
351 sno number primary key,
352 sname varchar2(20),
353 ssex char(2) default '男' check(ssex='男' or ssex='女'),
354 sage number,
355 sintime date,
356 --记录学生状态的列,1的时候为在读,0的时候则已经退学
357 sstatus number default 1 check(sstatus = 1 or sstatus = 0),
358 scno number,
359 foreign key(scno) references cls(cno)
360 )
361 --分数表(编号,成绩,学生编号)
362 create table mark(
363 mno number primary key,
364 mcj number(4,1) check(mcj >= 0),
365 msno number,
366 foreign key(msno) references stu(sno)
367 )
368
369 --添加初始化数据
370
371 --插入班级测试数据
372 insert into cls
373 select 1,'ST01' from dual
374 union
375 select 2,'ST02' from dual;
376
377 --插入老师测试数据
378 insert into teacher values(1,'涂老师','男',1);
379 insert into teacher values(2,'刘老师','女',1);
380 insert into teacher values(3,'陈老师','男',2);
381 insert into teacher values(4,'李老师','女',2);
382 insert into teacher values(5,'蔡老师','女',1);
383
384 --插入学生测试数据
385 insert into stu values(1,'小一','男',20,to_date('2016-6-13','yyyy-mm-dd'),default,1);
386 insert into stu values(2,'小二','男',21,to_date('2016-6-13','yyyy-mm-dd'),default,1);
387 insert into stu values(3,'小三','女',20,to_date('2016-6-13','yyyy-mm-dd'),default,1);
388 insert into stu values(4,'小四','男',19,to_date('2016-6-15','yyyy-mm-dd'),default,1);
389 insert into stu values(5,'小五','女',19,to_date('2016-6-15','yyyy-mm-dd'),default,1);
390 insert into stu values(6,'小六','男',21,to_date('2016-6-15','yyyy-mm-dd'),default,1);
391 insert into stu values(7,'小七','男',21,to_date('2016-6-20','yyyy-mm-dd'),0,1);
392 insert into stu values(8,'小八','女',20,to_date('2016-6-20','yyyy-mm-dd'),default,1);
393 insert into stu values(9,'小九','男',23,to_date('2016-6-21','yyyy-mm-dd'),default,1);
394 insert into stu values(10,'小十','男',21,to_date('2016-6-21','yyyy-mm-dd'),0,1);
395
396 insert into stu values(11,'大一','男',20,to_date('2016-7-3','yyyy-mm-dd'),default,2);
397 insert into stu values(12,'大二','男',21,to_date('2016-7-3','yyyy-mm-dd'),default,2);
398 insert into stu values(13,'大三','女',20,to_date('2016-7-3','yyyy-mm-dd'),default,2);
399 insert into stu values(14,'大四','男',19,to_date('2016-7-6','yyyy-mm-dd'),default,2);
400 insert into stu values(15,'大五','女',19,to_date('2016-7-6','yyyy-mm-dd'),default,2);
401 insert into stu values(16,'大六','男',21,to_date('2016-7-9','yyyy-mm-dd'),default,2);
402 insert into stu values(17,'大七','男',21,to_date('2016-7-9','yyyy-mm-dd'),default,2);
403 insert into stu values(18,'大八','女',20,to_date('2016-7-9','yyyy-mm-dd'),default,2);
404 insert into stu values(19,'大九','男',23,to_date('2016-7-13','yyyy-mm-dd'),0,2);
405 insert into stu values(20,'大十','男',21,to_date('2016-7-13','yyyy-mm-dd'),default,2);
406
407 --插入分数测试数据
408 insert into mark values(1,90,1);
409 insert into mark values(2,80,1);
410 insert into mark values(3,92,2);
411 insert into mark values(4,91,3);
412 insert into mark values(5,58,4);
413 insert into mark values(6,64,5);
414 insert into mark values(7,72,11);
415 insert into mark values(8,65,12);
416 insert into mark values(9,58,12);
417 insert into mark values(10,96,13);
418 insert into mark values(11,91,15);
419 insert into mark values(12,53,7);
420 insert into mark values(13,61,7);
421
422
423 题目:
424 1.请查询出名字带'小'的21岁以上在读男生信息
425
426 2.请查询出‘ST01’班级的所有在读女生的姓名与性别以及'ST02'班级所有在读男生的姓名与性别
427
428 3.请查询出和“小二”同学入学日期中的“日”相同的所有在读学生信息
429
430 4.请统计各班在读男生人数以及女生人数并按人数倒序排序
431
432 5.请查询出所有考试两次的在读学员信息
433
434 6.请查询名为“小一”所在班级的所有教师信息
435
436 7.请查询出班级学生平均分最高的班级名称
437
438 8.请查询出所有班级的在读学生的姓名、分数
439
440 9.请查询出所有涂老师所在班级的在读学生的姓名、分数
441
442 10.请统计各班级在读学生人数以及教师人数
443
444
445 //由于时间关系没能完全做完这些练习
446
447