FROM S
WHERE SNAME=’WANG’);
6 在表SC中检索成绩为空值的学生学号和课程号。
SELECT S#, C#
FROM SC
WHERE GRADE IS NULL;
7 检索姓名以L打头的所有学生的姓名和年龄。
SELECT SNAME, AGE
FROM S
WHERE SNAME LIKE ’L%’;
8 求年龄大于女同学平均年龄的男学生姓名和年龄。
SELECT SNAME, AGE
FROM S
WHERE SEX=’M’
AND AGE>(SELECT AVG(AGE)
FROM S
WHERE SEX=’F’);
9 求年龄大于所有女同学年龄的男学生姓名和年龄。
SELECT SNAME, AGE
FROM S
WHERE SEX=’M’ AND AGE>ALL(SELECT AGE
FROM S
WHERE SEX=’F’);
习题3.12
试用SQL更新语句表达对3.2题教学数据库中关系S、SC、C的更新操作:
1 往关系C中插一个课程元组('C8','VC++','BAO')。
INSERT INTO C
VALUES('C8','VC++','BAO');
② 检索所授每门课程平均成绩均大于80分的教师姓名,并把检索到的值送往另一个已存在的表FACULTY(TNAME)。
INSERT INTO FACULTY(TNAME)
SELECT DISTINCT TEACHER
FROM (SELECT TEACHER, C.C#, AVG(GRADE)
FROM S, SC
WHERE SC.C#=C.C#
GROUP BY TEACHER, C.C#) AS RESULT(TEACHER, C#, AVG_GRADE) AS X WHERE 80<=ALL(SELECT AVG_GRADE
FROM RESULT AS Y
WHERE Y.TEACHER=X.TEACHER);
③在SC中删除尚无成绩的选课元组。
DELETE FROM SC
WHERE GRADE IS NULL;
④ 把选修LIU老师课程的女同学选课元组全部删去。
DELETE FROM SC
WHERE S# IN(SELECT S# FROM S WHERE SEX='F')
AND C# IN(SELECT C# FROM C WHERE TEACHER='LIU');
⑤ 把MATHS课不及格的成绩全改为60分。
UPDATE SC
SET GRADE=60
WHERE GRADE<60 AND C# IN(SELECT C#
FROM C
WHERE CNAME='MATHS');
⑥ 把低于所有课程总平均成绩的女同学成绩提高5%。
UPDATE SC
SET GRADE=GRADE*1.05
WHERE S# IN(SELECT S#
FROM S
WHERE SEX='F')
AND GRADE<(SELECT AVG(GRADE)
FROM SC);
⑦ 在表SC中修改C4课程的成绩,若成绩小于等于70分时提高5%,若成绩大于70 分时提高4%(用两种方法实现,一种方法是用两个UPDATE语句实现,另一种方法是用带CASE操作的一个UPDATE语句实现)。
UPDATE SC
SET GRADE=GRADE*CASE
WHEN GRADE>70 THEN 1.04 ELSE 1.05 END
WHERE C#='C4';
⑧ 在表SC中,当某个成绩低于全部课程的平均成绩时,提高5%。
UPDATE SC
SET GRADE=GRADE*1.05
WHERE GRADE<(SELECT AVG(GRADE) FROM SC);
习题3.13
设数据库中有三个关系:
职工表 EMP(E#,ENAME,AGE,SEX,ECITY),
其属性分别表示职工工号、姓名、年龄、性别和籍贯。
工作表 WORKS(E#,C#,SALARY),
其属性分别表示职工工号、工作的公司编号和工资。
公司表 COMP(C#,CNAME,CITY),
其属性分别表示公司编号、公司名称和公司所在城市。
试用SQL语句写出下列操作:
① 用CREATE TABLE语句创建上述三个表,需指出主键和外键。
CREATE TABLE EMP
( E# CHAR(4) NOT NULL, ENAME CHAR(8) NOT NULL,
(2003/9/21) (GJ-DA) (共2页) 目录--36
AGE SMALLINT, SEX CHAR
(1), ECITY CHAR(20), PRIMARY KEY(E#)); CREATE TABLE COMP
( C# CHAR(4) NOT NULL,
CNAME CHAR(20) NOT NULL, CITY CHAR(20), PRIMARY KEY(C#));
CREATE TABLE WORKS
( E# CHAR(4) NOT NULL, C# CHAR(4) NOT NULL, SALARY SMALLINT, PRIMARY KEY(E#, C#),
FOREIGN KEY(E#) REFERENCES EMP(E#), FOREIGN KEY(C#) REFERENCES COMP(C#));
2 检索超过50岁的男职工的工号和姓名。
SELECT E#, ENAME
FROM EMP
WHERE AGE>50 AND SEX='M';
3 假设每个职工只能在一个公司工作,检索工资超过1000元的男性职工工号和姓名。
SELECT EMP.E#, ENAME
FROM EMP, WORKS
WHERE EMP.E#=WORKS.E# AND SALARY>1000;
4 假设每个职工可在多个公司工作,检索在编号为C4和C8公司兼职的职工工号和姓名。
SELECT A.E#, A.ENAME
FROM EMP A, WORKS B, WORKS C WHERE A.E#=B.E# AND B.E#=C.E#
AND B.C#='C4' AND C.C#='C8';
⑤ 检索在“联华公司”工作、工资超过1000元的男性职工的工号和姓名。
SELECT A.E#, A.ENAME
FROM EMP A, WORKS B, COMP C WHERE A.E#=B.E# AND B.C#=C.C#
AND CNAME='联华公司' AND SALARY>1000 AND SEX='M';
⑥ 假设每个职工可在多个公司工作,检索每个职工的兼职公司数目和工资总数.显示(E#,NUM,SUM_SALARY),分别表示工号、公司数目和工资总数。
SELECT E#, COUNT(C#) AS NUM, SUM(SALARY) AS SUM_SALARY
FROM WORKS GROUP BY E#;
⑦ 工号为E6的职工在多个公司工作,试检索至少在E6职工兼职的所有公司工作的职工工号。
SELECT X.E#
FROM WORKS X WHERE NOT EXISTS
(SELECT *
FROM WORKS Y
WHERE E#='E6' AND NOT EXISTS
(SELECT *
FROM WORKS Z
WHERE Z.E#=X.E# AND Z.C#=Y.C#));
⑧ 检索联华公司中低于本公司平均工资的职工工号和姓名。
SELECT A.E#, A.ENAME
FROM EMP A, WORKS B, COMP C WHERE A.E#=B.E# AND B.C#=C.C#
AND CNAME='联华公司'
AND SALARY<(SELECT AVG(SALARY)
FROM WORKS, COMP
WHERE WORKS.C#=COMP.C#
AND CNAME='联华公司');
⑨在每一公司中为50岁以上职工加薪100元(若职工为多个公司工作,可重复加)。
UPDATE WORKS
SET SALARY=SALARY+100
WHERE E# IN (SELECT E# FROM EMP WHERE AGE>50);
10 在EMP表和WORKS表中删除年龄大于60岁的职工有关元组。
DELETE FROM WORKS WHERE E# IN (SELECT E# FROM EMP WHERE AGE>60);
DELETE FROM EMP
WHERE AGE>60;