数据库课后习题自测

余生长醉 提交于 2020-03-12 09:04:46

数据库课后习题

习题2自测

二、设计题

/*1.设某商业集团中有若干公司,人事数据库中有3个基本表:
职工关系  EMP(E# ENAME,AGE .SEX,ECITY其属性分别表示职工工号、姓名、年龄、性别和居佳城市。

工作关系 WORKS(E# ,C# ,SALARY)其属性分别表示职工工号、工作的公司编号和工资。

公司关系 COMP(C# ,CNAME,CITY,MGR. E#)其属性分别表示公司编号、公司名称公司所在城市和公司经理的工号,

在3个基本表中,字段AGE和SALARY为效值型,其他字段均为字符型。请完成以下操作:*/


-- (1)检索超过50岁的男职工的工号和姓名。
由于E#中的#表示注释,所以此处用$代替。

SELECT E#,ENAME FROM EMP 
WHERE AGE>50 AND SEX='男';

-- (2)假设每个职工可以在多个公司工作,检索每个职工的兼职公司数目和工资总数,显示(E#,NUM,SUM_SALARY),分别表示工号,公司数目和工资总数。
-- SELECT E#,COUNT(C#),SALARY FROM EMP E,WORKS W
-- WHERE E.E#=W.E# ;

-- 正解:分组检索,每个职工
SELECT E#,COUNT(*)NUM,SUM_SALARY FROM  WORKS GROUP BY E#;


-- (3)检索联华公司中低于本公司职工平均工资的所有职工的工号和姓名。
-- 错解
SELECT E#,ENAME FROM EMP E,WORKS W,COMP C
WHERE E.E#=W.E#,W.C#=C.C#;

-- 正解:涉及到几个表,而且不同表中有相同的列名,因此select后面用别名来区分选择某个表中的某列。
SELECT E.E#,ENAME
FROM EMP E, WORKS W, COMP C
WHERE E.E#=W.E# AND W.C#=C.C# AND CNAME='联华公司' 
AND SALARY <(SELECT AVG(SALARY) FROM WORKS,COMP
            WHERE WORKS.C#=COMP.C# AND CNAME='联华公司');

-- (4)检索职工人数最多的公司的编号和名称。
-- 错误:还有条件没有进行限制,而且count的用法用错了
-- count用法参考:https://blog.csdn.net/Chenftli/article/details/92411239?
SELECT C#,CNAME FROM COMP, WORKS W
WHERE COUNT(W.E#) >=ALL
(SELECT COUNT(W.E#) FROM WORKS
GROUP BY C#)

-- 正解
SELECT C.C#,CNAME FROM WORKS B,COMP C
WHERE B.C#=C.C#
GROUP BY C.C#,CNAME
HAVING COUNT(*)>=ALL(SELECT COUNT(*) FROM WORKS GROUP BY C#);


-- (5)检索平均工资高于联华公司平均工资的公司的公司编号和名称。存在疑问
-- 错误:where后面不能接聚合函数
SELECT C.C#,CNAME FROM COMP C,WORKS W
WHERE C.C#=W.C# AND AVG(SALARY)>
(SELECT AVG(SALARY) FROM WORKS,COMP
WHERE WORKS.C#=COMP.C# AND CNAME='联华公司');

-- 正解
SELECT C.C#,CNAME FROM COMP C,WORKS W
WHERE C.C#=W.C#
GROUP BY C.C#,CNAME
HAVING AVG(SALARY)>
(SELECT AVG(SALARY) FROM WORKS,COMP
WHERE WORKS.C#=COMP.C# AND CNAME='联华公司');

-- (6)为联华公司的职工加薪5%。
-- 错误  语句用错,本质不是检索语句
SELECT W.E# FROM WORKS W,COMP C
WHERE W.C#=C.C# AND CNAME='联华公司'
SET SALARY=1.05*SALARY;

-- 正解
UPDATE WORKS SET SALARY = SALARY*1.05
WHERE C# IN(SELECT C# FROM COMP
           WHERE CNAME='联华公司');

-- (7)在WORKS表中删除年龄大于60岁的职工记录。

DELETE * FROM WORKS
WHERE E# IN(SELECT E# FROM EMP
           WHERE AGE>60);


-- (8)建立一个有关女职工的视图emp woman,属性包括E#、ENAME C#、CNAME、SALARY,然后对视图empwoman
-- 进行操作,检索每一位女职工的工资总数(假设每个职工可在多个公司兼职)。

(1)建立视图
CREATE VIEW emp_woman AS
SELECT E.E#,ENAME,C.C#,CNAME,SALARY
FROM EMP E,WORKS W,COMP C
WHERE E.E#=W.E# AND W.C#=C.C# AND SEX='女';

(2)检索
SELECT E#,SUM(SALARY) FROM emp_woman GROUP BY E#;




2.某工厂的信息管理数据库中有以下两个关系模式:
职工(职工号,姓名,年龄,月工资,部门号,电话,办公室)
部门(部门号,部门名,负责人代码,任职时间)

(1)查询每个部门中月工资最高的“职工号”的SQL查询语句如下:
SELECT 职工号 FROM 职工E
WHERE月工资=(SELECT MAX(月工资)
FROM 职工M 
WHERE M.部门号=E.部门号);

-- ①请用30字以内的文字简要说明该查询语句对查询效率的影响

答:对于外层的职工关系E中的每一个元组,都要对内层的整个职工关系进行检索,查询效率不高。

-- ②对该查询语句进行修改,使它既可以完成相同功能,又可以提高查询效率。
解决方法一:先把每个部门最高工资的数据存入临时表,再对临时表进行查询
CREATE TABLE TEMP
AS SELECT 部门号,MAX(月工资) 最高工资 FROM 职工 GROUP BY 部门号;

SELECT 职工号 FROM 职工,temp
WHERE 职工.部门号=temp.部门号 AND 月工资=最高工资;

解决方法二:直接在from子句中使用临时表结构

SELECT 职工号 
FROM 职工,(SELECT MAX(月工资)最高工资,部门号
        FROM 职工
        GROUP BY 部门号)AS depMAX
        WHERE 月工资=最高工资 AND 职工.部门号=depMAX.部门号
        

(2)假定分别在“职工”关系中的“年龄”和“月工资”字段上创建了索引,如下的SELECT查询语句可能不会促使查询优化
器使用索引,从而降低了查询效率,请写出既可以完成相同功能又可以提高查询效率的SQL语句.
SELECT  姓名,年龄,月工资 FROM 职工
WHERE 年龄>45 OR月工资< 1000;

解答:(SELECT 姓名,年龄,月工资 FROM 职工 WHERE 年龄>45)
UNION
(SELECT 姓名,年龄,月工资 FROM 职工 WHERE 工资<1000)







易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!