设数据库中有3个关系:
职工表EMP(E#,ENAME,AGE,SEX,ECITY),其属性分别表示职工工号、姓名、年龄、性别和籍贯。
公司表 COMP(C#,CNAME,CITY),其属性分别表示公司编号、公司名称和公司所在城市。
工作表WORKS(E#,C#,SALARY),其属性分别表示职工工号、工作的公司编号和工资。
试用SQL语言写出下列操作:(每小题2分,总计18分)
(1)检索超过50岁的男职工的工号和姓名。
2)假设每个职工只能在一个公司工作,检索工资超过1000元的男性职工工号和姓名。
3)假设每个职工可在多个公司工作,检索在编号为C4和C8公司兼职的职工工号和姓名。
4)检索在“联华公司”工作、工资超过1000元的男性职工的工号和姓名。
5)假设每个职工可在多个公司工作,检索每个职工的兼职公司数目和工资总数,显示(E#,NUM,SUM_SALARY),分别表示工号、公司数目和工资总数。
6)工号为E6的职工在多个公司工作,试检索至少在E6职工兼职的所以公司工作的职工工号。
7)检索联华公司中低于本公司平均工资的职工工号和姓名。
8)在每个公司中为50岁以上职工加薪100元(若职工为多个公司工作,可重复加)。
9)在EMP表和WORKS表中删除年龄大于60岁的职工有关元组。
信息来源于生活,如有雷同纯属巧合。
CREATE table EMP(
E VARCHAR(2) constraint pk_EMP primary key,
Ename VARCHAR(10) not null,
age NUMBER(3) CHECK(age>0 AND age<120),
sex char(2) check ( sex in('男','女')),
Ecity varchar(12)
);
INSERT into EMP(E,Ename,age,sex,Ecity) VALUES ('E1','小胖','28','男','哈尔滨');
INSERT into EMP(E,Ename,age,sex,Ecity) VALUES ('E2','燕燕','22','女','北京');
INSERT into EMP(E,Ename,age,sex,Ecity) VALUES ('E3','大泽','67','男','青岛');
INSERT into EMP(E,Ename,age,sex,Ecity) VALUES ('E4','威达','63','男','常德');
INSERT into EMP(E,Ename,age,sex,Ecity) VALUES ('E5','鹏飞','37','男','郑州');
INSERT into EMP(E,Ename,age,sex,Ecity) VALUES ('E6','黄伦','43','女','大连');
INSERT into EMP(E,Ename,age,sex,Ecity) VALUES ('E7','佳慧','26','女','濮阳');
INSERT into EMP(E,Ename,age,sex,Ecity) VALUES ('E8','焰锋','52','男','汉口');
信息来源于生活,如有雷同纯属巧合。
CREATE TABLE COMP(
C VARCHAR(4) Constraint pk_Comp primary key,
Cname VARCHAR(12) Constraint u_Comp unique,
City VARCHAR(12) not null
);
INSERT into COMP(C,Cname,City) VALUES('C1','微软','北京');
INSERT into COMP(C,Cname,City) VALUES('C2','万达','大连');
INSERT into COMP(C,Cname,City) VALUES('C3','华为','深圳');
INSERT into COMP(C,Cname,City) VALUES('C4','腾讯','深圳');
INSERT into COMP(C,Cname,City) VALUES('C5','东软','大连');
INSERT into COMP(C,Cname,City) VALUES('C6','武钢','武汉');
INSERT into COMP(C,Cname,City) VALUES('C7','联华公司','濮阳');
INSERT into COMP(C,Cname,City) VALUES('C8','茅台','贵州');
INSERT into COMP(C,Cname,City) VALUES('C9','京东','北京');
INSERT into COMP(C,Cname,City) VALUES('C10','阿里巴巴','杭州');
信息来源于生活,如有雷同纯属巧合。
CREATE TABLE Works(
E VARCHAR(2),
C VARCHAR(4),
Salary NUMBER(10) check(salary>0),
Constraint fk_e foreign key(E) references EMP(E),
Constraint fk_c foreign key(C) references COMP(C)
);
INSERT into Works(E,C,Salary) VALUES('E1','C3','200');
INSERT into Works(E,C,Salary) VALUES('E1','C5','900');
INSERT into Works(E,C,Salary) VALUES('E2','C1','3000');
INSERT into Works(E,C,Salary) VALUES('E2','C2','1000');
INSERT into Works(E,C,Salary) VALUES('E2','C8','500');
INSERT into Works(E,C,Salary) VALUES('E2','C6','300');
INSERT into Works(E,C,Salary) VALUES('E3','C3','320');
INSERT into Works(E,C,Salary) VALUES('E3','C7','1050');
INSERT into Works(E,C,Salary) VALUES('E3','C9','250');
INSERT into Works(E,C,Salary) VALUES('E3','C10','120');
INSERT into Works(E,C,Salary) VALUES('E4','C1','240');
INSERT into Works(E,C,Salary) VALUES('E4','C4','20');
INSERT into Works(E,C,Salary) VALUES('E4','C6','400');
INSERT into Works(E,C,Salary) VALUES('E5','C5','600');
INSERT into Works(E,C,Salary) VALUES('E5','C6','1200');
INSERT into Works(E,C,Salary) VALUES('E5','C7','900');
INSERT into Works(E,C,Salary) VALUES('E5','C4','200');
INSERT into Works(E,C,Salary) VALUES('E6','C7','400');
INSERT into Works(E,C,Salary) VALUES('E6','C8','5000');
INSERT into Works(E,C,Salary) VALUES('E6','C4','200');
INSERT into Works(E,C,Salary) VALUES('E6','C3','20');
INSERT into Works(E,C,Salary) VALUES('E7','C1','300');
INSERT into Works(E,C,Salary) VALUES('E7','C2','25');
INSERT into Works(E,C,Salary) VALUES('E7','C3','650');
INSERT into Works(E,C,Salary) VALUES('E8','C2','4200');
INSERT into Works(E,C,Salary) VALUES('E8','C7','21');
简单的单表条件查询,大于50岁,男职工
select E,Ename from EMP where sex = '男' AND age>50;
可以做连接查询也可以做子查询,个人认为双表连接查询更容易。
select EMP.E,EMP.ENAME from EMP,WORKS
where EMP.E = WORKS.E AND EMP.SEX = '男' AND WORKS.SALARY>1000;
子查询
select E,Ename from EMP where E in
(select DISTINCT E from WORKS where C = 'C4' OR C = 'C8');
三表连接比较简单,也可以多重子查询
//连接查询
select EMP.E,EMP.Ename from EMP,WORKS,COMP
where EMP.E = WORKS.E AND COMP.C = WORKS.C AND
EMP.SEX = '男' AND WORKS.SALARY>1000 AND COMP.CNAME='联华公司';
//多重子查询
select E,Ename from EMP where sex='男' AND E IN(
select E from WORKS where
(C in (SELECT C from COMP where CNAME = '联华公司')) AND salary>1000);
使用聚集函数count()求职工的兼职公司数目;
使用聚集函数sum()求职工的工资总数;
以职工编号E分组(group by);
为使结果好看使用order by语句对升序员工编号升序排序;
仅涉及单表查询
select E,COUNT(C) NUM,Sum(salary) SUM_SALARY
from WORKS
GROUP BY E
ORDER BY E;
相关子查询
wow,表没有配置好,查询结果显示所有表中职工都在C3,C4,C7,C8公司任职
select DISTINCT E from WORKS where C
in (select C from WORKS where E = 'E6')
ORDER BY E;
这个小题饶了很大弯,有简便方法还请不吝赐教。
思路:先把联华公司的公司编号C和平均工资求出来视为表tb;
然后与works表连接查询,选出符合条件的员工的员工编号E;
再做从EMP表做相关子查询选出E和Ename
//四层嵌套子查询
select EMP.E,EMP.ENAME from EMP where E in(
(select WORKS.E from WORKS,
(select C,avg(salary) avg_SALARY
from WORKS
where C in(select C from COMP where cname = '联华公司')
GROUP BY C) tb
where WORKS.C=TB.C AND WORKS.SALARY
从上面可以知道,50岁以上的职工有E3,E4,E8。
使用update语句更新即可。
update WORKS set SALARY = SALARY+100
where E in
(select E from EMP where EMP.age>50);
年龄大于60岁的职工为E3,E4。
delete from WORKS where E in
(select E from EMP where age>60);
delete from EMP where age>60;