第3章 SQL 习题 - 3.12

3.12使用大学模式,用SQL写出如下查询。

a.创建一门课程"CS-001",其名称为"Weekly Seminar",学分为0.

insert into course values('CS-001', 'Weekly Seminar', NULL, 0);

插入失败,原因如下:

ERROR:  new row for relation "course" violates check constraint "course_credits_check"
DETAIL:  Failing row contains (CS-001, Weekly Seminar, null, 0).
SQL state: 23514

原来是违反了字段检查规则,因为我们在创建course关系的时候,对credits学分这个字段有限制,要求大于0。

create table course
	(course_id		varchar(8), 
	 title			varchar(50), 
	 dept_name		varchar(20),
	 credits		numeric(2,0) check (credits > 0),
	 primary key (course_id),
	 foreign key (dept_name) references department
		on delete set null
	);

为了能成功插入数据,将学分改成1:

insert into course values('CS-001', 'Weekly Seminar', NULL, 1);

b.创建该课程在2009年秋季的一个课程段,sec_id为1.

insert into section values('CS-001', '1', 'Fall', 2009);

c.让Comp. Sci.系的每个学生都选修上述课程段。

insert into takes 
	select ID, 'CS-001', '1', 'Fall', 2009
	from student where dept_name = 'Comp. Sci.';

d.删除名为Chavez的学生选修上述课程段的信息。

delete from takes where
course_id = 'CS-101' and sec_id = '1' and semester = 'Fall' 
and year = 2009 and ID = (select ID from student where name = 'Chavez');

e.删除课程CS-001。如果在运行此删除语句之前,没有先删除这门课程的授课信息(课程段),会发现什么事情?

课程段关系对课程关系设置了外码依赖,当依赖的course关系删除某个课程的时候,自动删除该课程的所有授课信息,我们可以看一下课程段的DDL:

create table section
	(course_id		varchar(8), 
         sec_id			varchar(8),
	 semester		varchar(6)
		check (semester in ('Fall', 'Winter', 'Spring', 'Summer')), 
	 year			numeric(4,0) check (year > 1701 and year < 2100), 
	 building		varchar(15),
	 room_number		varchar(7),
	 time_slot_id		varchar(4),
	 primary key (course_id, sec_id, semester, year),
	 foreign key (course_id) references course
		on delete cascade,
	 foreign key (building, room_number) references classroom
		on delete set null
	);

注意这条语句

foreign key (course_id) references course
        on delete cascade

现在我们开始删除课程CS-001,看看会发生什么。

delete from course where course_id = 'CS-001';

再检查一下课程段里是否还有该课程的授课信息:

select * from section where course_id = 'CS-001';
 course_id | sec_id | semester | year | building | room_number | time_slot_id 
-----------+--------+----------+------+----------+-------------+--------------
(0 rows)

f.删除课程名称中包含'database'的任意课程的任意课程段所对应的所有takes元组,在课程名的匹配中忽略大小写。

delete from takes where (course_id, sec_id, semester, year) in (
	select course_id, sec_id, semester, year from section natural join
	course where lower(title) like '%database%'
);

为了验证我们做的对不对,咱们先从course关系中找找包含database的课程都有哪些。

select * from course where lower(title) like '%database%';
 course_id |          title           | dept_name  | credits 
-----------+--------------------------+------------+---------
 CS-347    | Database System Concepts | Comp. Sci. |       3
(1 row)

这个课程的ID为CS-347,我们只要看看takes里有没有为这个ID的课程,就能知道刚才的删除有没有成功了。

select * from takes where course_id = 'CS-347';
 id | course_id | sec_id | semester | year | grade 
----+-----------+--------+----------+------+-------
(0 rows)

猜你喜欢

转载自blog.csdn.net/zhangyingli/article/details/84196092