綜合練習
所有答案都驗證過3遍,符合題意且結果正確,如有疑問可留言
1. 創建數據庫和數據庫表
- 這麼簡單自己按照表建
2. 簡單的數據查詢
- 查詢所有同學的基本信息,包括:學號s_no、班級號class_no、姓名s_name、性別s_sex、出生日期s_birthday。
select s_no,class_no,s_name,s_sex,s_birthday from Student
或
select * from Student
- 查詢所有同學,要求顯示其學號s_no、姓名s_name。
select s_no,s_name from Student
- 查詢所有男同學,要求顯示其學號s_no、姓名s_name、出生日期s_birthday。
select s_no,s_name,s_birthday from Student where s_sex='男'
- 查詢所有出生日期在“1980-01-01”前的女同學,要求顯示其學號s_no、姓名s_name、性別s_sex、出生日期s_birthday。
select s_no,s_name,s_sex,s_birthday from Student where s_sex='女' and s_birthday<'1980-01-01'
- 查詢所有姓“李”的男同學,要求顯示其學號s_no、姓名s_name、出生日期s_birthday。
select s_no,s_name,s_birthday from Student Where s_sex='男' and s_name like '李%'
- 查詢所有姓名中含有“一”字的同學,要求顯示其學號s_no、姓名s_name。
select s_no,s_name from Student where s_name like '%一%'
- 查詢所有職稱不是“講師”的教師,要求顯示其教師號t_no、姓名t_name、職稱t_title。
select t_no,t_name,t_title from Teacher where t_title <> '講師'
- 查詢雖選修了課程,但未參加考試的所有同學,要求顯示出這些同學的學號s_no。
select s_no from Choice where score IS NULL
- 查詢所有考試不及格的同學,要求顯示出這些同學的學號s_no、成績score,並按成績降序排列。
select s_no,score from Choice where score<60 or score IS NULL order by score DESC
- 查詢出課程號爲01001、02001、02003的所有課程,要求顯示出課程號course_no、課程名稱course_name。(要求用in運算符)
select course_no,course_name from Course where course_no in('01001','02001','02003')
- 查詢所有在1970年出生的教師,要求顯示其教師號t_no、姓名t_name、出生日期t_birthday。
-- 這裏需要注意是使用雙%,具體原因我也不清楚,總之用雙%結果就沒錯
select t_no,t_name,t_birthday from Teacher Where t_birthday like '%1970%'
- 查詢出各個課程號course_no及相應的選課人數。
select course_no,COUNT(course_no) AS 選課人數 from Choice GROUP BY course_no
- 查詢出教授兩門以上課程的教師號t_no。
-- 注意,這裏原表中並沒有教授2門以上的教師,可自己加一位教授3門課的教師上去
select t_no from Teaching GROUP BY t_no HAVING COUNT(t_no)>2
- 查詢出選修了01001課程的學生平均分、最低分數及最高分數。
select AVG(score) AS 平均分,MIN(score) AS 最低分數,MAX(score) AS 最高分數
from Choice where course_no='01001'
- 查詢1960年以後出生的,職稱爲講師的教師的姓名t_name、出生日期t_birthday,並按出生日期升序排列。
select t_name,t_birthday from Teacher where t_title='講師' and t_birthday>'1960-12-31' order by ASC
3. 複雜的數據查詢
- 查詢所有同學的選課情況及成績情況,要求顯示學生的學號s_no、姓名s_name、課程號course_no和課程的成績score。
select s.s_no,s_name,course_no,score
from Student s left JOIN Choice ch ON s.s_no=ch.s_no
order by s_no
- 查詢所有同學的選課及成績情況,要求顯示學生的姓名s_name、課程名稱course_name、課程的成績score,並將查詢結果存放到一個新的數據表new_table中。
select s_name,course_name,score into new_table
from Student s LEFT JOIN Choice ch ON s.s_no=ch.s_no
LEFT JOIN Course c ON ch.course_no=c.course_no
-- 結果存在new_table 表中,查詢結果
select * from new_table
- 查詢“計算機99-1”班的同學的選課及成績情況,要求顯示學生的學號s_no、姓名s_name、課程號course_no、課程名稱course_name、課程的成績score。
select s.s_no,s_name,ch.course_no,course_name,score
from Student s LEFT JOIN Class c
ON s.class_no=c.class_no
LEFT JOIN Choice ch ON s.s_no=ch.s_no
LEFT JOIN Course co ON ch.course_no=co.course_no
where class_name='計算機99-1'
- 查詢所有同學的學分情況(假設課程成績≥60分時可獲得該門課程的學分),要求顯示學生的學號s_no、姓名s_name、總學分(將該列定名爲:total_score)(用JOIN)
select s.s_no,s_name,sum(co.course_score) as total_score
from Student as s
left join Choice as c on c.s_no=s.s_no
left join Course as co on co.course_no=c.course_no
and c.score>='60'
group by s.s_no,s.s_name
- 查詢所有同學的平均成績及選課門數,要求顯示學生的學號s_no、姓名s_name、平均成績(將該列定名爲average_score)、選課的門數(將該列定名爲:choice_num)。
select s.s_no,s_name,AVG(score) AS average_score,COUNT(score) AS choice_num
from Student s LEFT JOIN Choice ch ON s.s_no=ch.s_no
GROUP BY s.s_no,s_name
- 查詢所有選修了課程但未參加考試的所有同學及相應的課程,要求顯示學生的學號s_no、姓名s_name、課程號course_no、課程名稱course_name。
select s.s_no,s_name,ch.course_no,course_name
from Student s inner JOIN Choice ch ON s.s_no=ch.s_no
inner JOIN Course c ON ch.course_no=c.course_no
where score IS NULL
- 查詢所有選修了課程但考試不及格(假設<60分爲不及格)的所有同學及相應的課程,要求顯示學生的學號s_no、姓名s_name、姓名s_name、課程號course_no、課程名稱course_name、學分course_score。
select s.s_no,s_name,co.course_no,course_name,course_score
from Student s inner JOIN Choice ch ON s.s_no=ch.s_no
inner JOIN Course co ON ch.course_no=co.course_no
where score < 60
- 查詢選修了課程名爲“程序設計語言”的所有同學及成績情況,要求顯示學生的姓名s_name、課程的成績score。(使用ANY)
select s_name,score
from Student s,Choice ch
where s.s_no=ch.s_no AND
ch.course_no=ANY(
select c.course_no from Course c where course_name='程序設計語言')
- 查詢“計算機系”的所有同學及成績情況,要求顯示學生的學號s_no、姓名s_name、班級名稱class_name、課程號course_no、課程名稱course_name、課程的成績score。
select s.s_no,s_name,class_name,co.course_no,course_name,score
from Student s left JOIN Choice ch ON s.s_no=ch.s_no
left JOIN Class c ON s.class_no=c.class_no
left JOIN Course co ON ch.course_no=co.course_no
where class_dept='計算機系'
- 查詢所有教師的任課情況,要求顯示教師姓名t_name、擔任課程的名稱course_name。
select t_name,course_name
from Teacher t left JOIN Teaching ti ON t.t_no=ti.t_no
left JOIN Course co ON ti.course_no=co.course_no
- 查詢所有教師的任課門數,要求顯示教師姓名t_name、擔任課程的門數(將該列定名爲course_number)。
select t_name,count(course_no) AS course_number
from Teacher t left JOIN Teaching ti ON t.t_no=ti.t_no
group by t.t_no,t_name
- 查詢和“李建國”是同一班級的同學的姓名。(使用子查詢)
select s_name from Student
where class_no=(
select class_no from Student
where s_name='李建國'
) AND s_name<>'李建國'
- 查詢沒有選修“計算機基礎”課程的學生姓名。(用NOT EXISTS)
select s_name from Student s
where NOT EXISTS (
select * from Course co inner JOIN Choice ch ON co.course_no=ch.course_no
where course_name='計算機基礎' AND s.s_no=ch.s_no
)
- 查詢主講“數據庫原理與應用”和主講“數據結構”的教師姓名。(用UNION)
select t_name from Teacher t
inner JOIN Teaching ti ON t.t_no=ti.t_no
inner JOIN Course co ON ti.course_no=co.course_no
where course_name='數據庫原理與應用'
UNION
select t_name from Teacher t
inner JOIN Teaching ti ON t.t_no=ti.t_no
inner JOIN Course co ON ti.course_no=co.course_no
where course_name='數據結構'
- 查詢講授了所有課程的教師的姓名。
本題需要自己插入一位教授所有課程的老師
insert into Teacher
values('000011','測試員','男','1970-2-3','講師')
還需要在任課情況表Teaching添加任課信息
insert into Teaching values
('01001','000011'),
('01002','000011'),
('01003','000011'),
('02001','000011'),
('02002','000011'),
('02003','000011')
做法一:使用雙重NOT EXISTS
select t_name from Teacher t
where NOT EXISTS (
select * from Course co
where NOT EXISTS (
select * from Teaching ti
where t.t_no=ti.t_no
AND co.course_no=ti.course_no
)
)
做法二:使用group by + count。注意,count函數只能用在having中而不能在where中
select t_name from Teacher t,Teaching ti
where t.t_no=ti.t_no
group by t_name
having COUNT(ti.course_no)=(
select COUNT(co.course_no) from Course co
)
- 用T—SQL語句定義存儲過程
- 創建一個能向學生表Student中插入一條記錄的存儲過程Insert_student,該存儲過程需要五個參數,分別用來傳遞學號、班級、姓名、性別、出生日期五個值。
CREATE PROCEDURE Insert_student ( @s_no CHAR(10), @s_class CHAR(6), @s_name VARCHAR(10), @s_sex CHAR(2), @s_birthday datetime ) AS INSERT INTO Student(s_no,class_no,s_name,s_sex,s_birthday) VALUES (@s_no,@s_class,@s_name,@s_sex,@s_birthday)
- 寫出執行存儲過程Insert_student的SQL語句,向數據表Student中插入一個新同學,並提供相應的實參值(實參值由用戶自己給出)。
EXEC Insert_student @s_no='000001',@s_class='xx0002',@s_name='測試1', @s_sex='男',@s_birthday='1980-10-03'
- 創建一個向課程表Course中插入一門新課程的存儲過程Insert_course,該存儲過程需要三個參數,分別用來傳遞課程號、課程名、學分,但允許參數“學分”的默認值爲2,即當執行存儲過程Insert_course時,未給第三個參數“學分“提供實參值時,存儲過程將按默認值2進行計算。
CREATE PROCEDURE Insert_course ( @course_no char(5), @course_name char(20), @course_score numeric(6,2)=2 ) AS INSERT INTO Course(course_no,course_name,course_score) VALUES(@course_no,@course_name,@course_score)
- 執行存儲過程Insert_course,向課程數據表Course中插入一門新課程。分兩種情況寫出相應的SQL命令。第一種:提供三個實參值(三個實參由用戶提供)。第二中:只提供兩個實參,不提供學分對應的實參。比較兩者差異。
EXEC Insert_course @course_no='03001',@course_name='測試課程1',@course_score=6 EXEC Insert_course @course_no='03002',@course_name='測試課程2' select * from Course -- 查詢結果爲,測試課程1的學分爲6,而測試課程2的學分爲2
- 創建一個名稱爲query_student的存儲過程,該存儲過程的功能是從數據表Student中根據學號查詢某一同學的姓名s_name、班級class_no、性別s_sex、出生日期s_birthday。
GO CREATE PROCEDURE query_student ( @s_no CHAR(10) ) AS SELECT s_name,class_no,s_sex,s_birthday from Student where s_no=@s_no
- Transact-SQL語句自定義觸發器
- 創建一個向學生表Student中插入一新同學時能自動列出全部同學信息的觸發器Display_trigger。
GO CREATE TRIGGER Display_trigger ON Student AFTER INSERT AS SELECT * FROM Student GO
- 執行存儲過程Insert_student,向學生表中插入一新同學,看觸發器Display_trigger是否被執行。
EXEC Insert_student @s_no='000002',@s_name='觸發器',@s_class='xx0002', @s_sex='男',@s_birthday='1979-07-30'