| 【问题1】 根据上述说明,由SQL定义的“职工”和“部门”的关系模式,以及统计各部门的人数C、工资总数Totals、平均工资Averages的D_S视图如下所示,请在空缺处填入正确的内容。 Create Table 部门 (部门号 Char(1){{U}} (a) {{/U}} 部门名 Char(16), 负责人代码 Char(4), 任职时间 DATE, {{U}}(b) {{/U}} (职工号)); Create Table 职工 (职工号 Char(4), 姓名 Char(8), 年龄 NUMDER(3), 月工资 NUMDER(4), 部门号 Char(1), 电话 Char(8), 办公室 Char(8), {{U}}(a) {{/U}}(职工号), {{U}}(c) {{/U}}(部门号), CHECK({{U}} (d) {{/U}})); Create View D_S(D,C,Totals,Averages) As (Select 部门号,{{U}} (e) {{/U}} from 职工 {{U}} (f) {{/U}} |
| 【问题2】 对于表22-2、表22-3所示的“职工”和“部门”关系,请指出下列各行是否可以插入,为什么?
【正确答案】
【答案解析】(1)不能插入。它违反了实体完整性原则,因为其主键属性值已经存在。
(2)可以插入。尽管部门号、电话和办公室为空,但是它表示该职工暂时还没有分配到某个部门。
(3)不能插入。它违反了参照完整性。因为6在关系“部门”中不存在。
本题主要考查完整性定义的约束性。
先看看第一条记录,它的职工号是1001,在表22-2中已经存在该职工号的记录。因为“职工号”是“职工”关系的主键,它在表中不能重复出现,否则破坏了实体的完整性。因此该条记录不能插入。
在第二条记录中职工号没有重复,同时它可以先不录入部门号(表示是新职工,暂时还没有分配部门),因为在“职工”关系中“部门号”是外键,在定义中也没有约束它不能为空。因此该记录可以插入。
最后一条记录中,部门号是6,但是在“部门”关系中没有找到“部门号”是6的记录,因此不能做插入操作。否则,就违反了参照完整性规则。
问答题
【正确答案】
【答案解析】(1)和(2)都不能执行,因为使用分组和聚集函数定义的视图是不可更新的。
(3)不一定能执行,具体要看视图的返回值的情况。
(4)和(5)可以执行,因为给出的SQL语句与定义D_S视图的SQL语句合并起来验证有效。
做这种类型的题目时,只要把题目给出的SQL语句与定义该视图的SQL语句合并起来验证是否有效即可。在问题1的分析中,我们已经求出了定义该视图的SQL语句如下:
Create View D_S(D,C,Totals,Averages)AS (Select 部门号,Count (职工号), SUN (月工资),AVG (月工资) From 职工 Group by 部门号)
(1)合并结果为:Update职工Set部门号=3 Where 部门号 =4 Group by 部门号。因为Where中不能包括Group聚合函数,因此不能执行。
(2)合并结果为:Delete From 职工Where Count(职工号)>4 Group by 部门号,因此也不能执行。
(3)这种要看视图的返回值的情况。因此不一定能执行。
(4)可以。
(5)显然该语句能执行。
问答题
【正确答案】
【答案解析】(1)对于外层的“职工”关系E中的每一个元组,都要对内层的整个“职工”关系M进行检索,因此查询效率不高。
(2)本题可以有两种解法:
解答一:
改正后的SQL语句使用了临时表:
Select Max(月工资)as 最高工资,部门号Into Temp From 职工
Group by 部门号
Select 职工号 From 职工,Temp
Where 月工资=最高工资 And 职工.部门号=Temp.部门号;
解答二:
Select 职工号 From 职工,(Select Max(月工资) As 最高工资,部门号
Group by 部门号 As depMax
Where 月工资=最高工资 And 职工.部门号=depMax.部门号;
因为该SQL语句用了查询嵌套和聚集函数,所以这种方式的查询效率会受到很大的影响。可以把它改成:
Select Max(月工资)As maxgz,部门号Into Temp From 职工
Group by 部门号
Select 职工号 From 职工,Temp
Where 月工资=maxgz And 职工.部门号=Temp.部门号;
问答题
【正确答案】
【答案解析】Select 姓名,年龄,月工资 From 职工
Where 年龄>45
UNION
Select 姓名,年龄,月工资 From 职工
Where 月工资<1000;
因为该SQL语句用了查询嵌套和聚集函数,所以这种方式的查询效率会受到很大的影响。可以把它改成:
Select Max(月工资)As maxgz,部门号Into Temp From 职工
Group by 部门号
Select 职工号 From 职工,Temp
Where 月工资=maxgz And 职工.部门号=Temp.部门号;
在语句
Select 姓名,年龄。月工资 From 职工
Where 年龄>45 or 月工资<1000;
中,由于使用了条件“Or”,查询的时候变成了对全表的扫描,不会促使查询优化器使用索引,从而降低了查询效率。改正的方法是去掉“Or”,修改后的SQL语句如下:
Select 姓名,年龄,月工资 From 职工
Where 年龄>45
UNION
Select 姓名,年龄,月工资 From 职工
Where 月工资<1000;
|