第3章 SQL 習題 - 3.12
阿新 • • 發佈:2018-11-19
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)