由於須要提升一下sql的查詢能力,固然最快的方式就是作一些實際的題目了。選擇了這個sql的50題,此次大概作了前10題左右,把思路放上來,也是一個總結。sql
具體題目見:spa
https://zhuanlan.zhihu.com/p/72223558code
第一部分的題目主要使用的技術是連表查詢和子查詢,難倒不難,主要是要把思路轉換過來。blog
首先畫出一個各個表之間的關係圖(沒畫圖以前關係總是搞不清)get
1.查詢" 01 "課程比" 02 "課程成績高的學生的信息及課程分數class
學生的信息在表1當中,課程成績在表4當中,固然要用到連表查詢。效率
這裏頗有廣泛性的一個問題是:要從表4中找出Sid相同,可是Cid爲1的score大於Cid爲2的score的記錄。這裏要使用子查詢,分別限定條件爲Cid=‘1’,Cid='2',變成兩個表,再查知足條件的就很簡單了。select
select Student.SId,Student.Sname,Student.Sage,Student.Ssex,r.科目一成績,r.科目二成績 from study.dbo.Student right join (select t1.SId as 學生ID,t1.score as 科目一成績,t2.score as 科目二成績 from (select SId,score from study.dbo.SC where CId='01')as t1, (select SId,score from study.dbo.SC where CId='02')as t2 where t1.SId=t2.SId and t1.score>t2.score) as r on Student.SId=r.學生ID
join -- on這個也是經常使用的思路,當要鏈接兩個某一列相關的表時。im
1.1查詢存在" 01 "課程但可能不存在" 02 "課程的狀況(不存在時顯示爲 null )技術
和第一題思路相似,注意以01課程爲準,因此要用left join
select * from (select SId,score from study.dbo.SC where CId='01') as t1 left join (select SId,score from study.dbo.SC where CId='02') as t2 on t1.SId=t2.SId
1.2 查詢同時存在01和02課程的狀況
很簡單,用inner join,求兩表交集
select t1.SId,t1.score,t2.score from (select SId,score from study.dbo.SC where CId='01') as t1 inner join (select SId,score from study.dbo.SC where CId='02') as t2 on t1.SId=t2.SId
1.3查詢選擇了02課程但沒有01課程的狀況
個人思路是仍是用一個right join,而後判斷NULL值,不知道會不會比not in效率高。
select t2.SId,t2.score from (select SId,score from study.dbo.SC where CId='01') as t1 right join (select SId,score from study.dbo.SC where CId='02') as t2 on t1.SId=t2.SId where t1.score is null
2.查詢平均成績大於等於 60 分的同窗的學生編號和學生姓名和平均成績
確定要連表,有表一有表四。平均成績涉及到group by,對平均成績的限制涉及到having語句
select t1.SId,t1.avg_score,t2.Sname from ( select SId,AVG(score) as avg_score from study.dbo.SC group by SId having AVG(score)>60 ) as t1 inner join study.dbo.Student as t2 on t1.SId=t2.SId
3.查詢在 SC 表存在成績的學生信息
依然是連表查詢,表一的sid等於表四的sid,去除重複值使用DISTINCT便可
select DISTINCT Student.SId,Student.Sname,Student.Sage,Student.Ssex from study.dbo.SC inner join Student on SC.SId=Student.SId
4.查詢全部同窗的學生編號、學生姓名、選課總數、全部課程的總成績(沒成績的顯示爲 null )
依然是連表查詢,left join
select Student.*,t2.count_id,t2.avg_score from Student left join (select SId,count(CId) as count_id ,avg(score)as avg_score from study.dbo.SC group by SId) as t2 on Student.SId=t2.SId
4.1 查有成績的學生信息
inner join,不贅述
select Student.*,t2.count_id,t2.avg_score from Student inner join (select SId,count(CId) as count_id ,avg(score)as avg_score from study.dbo.SC group by SId) as t2 on Student.SId=t2.SId
5.查詢「李」姓老師的數量
最簡單的一題,知道like這種模糊查詢就行
select COUNT(*) from Teacher where Tname like '李%'
6.查詢學過「張三」老師授課的同窗的信息
這個有意思,表明着從一張表跳到另外一張表找信息
第一個思路固然是用join,多個表一個一個on鏈接起來
select Student.* from (select tid from Teacher where Tname='張三') as t1 inner join Course on t1.tid=Course.TId inner join SC on Course.CId=SC.CId inner join Student on SC.SId=Student.SId
可是也有另外一種寫法
select study.dbo.Student.* from teacher,study.dbo.Course ,study.dbo.student,study.dbo.sc where teacher.Tname='張三' and teacher.TId=Course.TId and Course.CId=sc.CId and sc.SId=student.SId
直接from多個表,在where裏寫=
我查了一下,其實這種方式是用了隱式的inner join,效率差別不大
7.查詢沒有學全全部課程的同窗的信息
查到沒有學全全部課程同窗的sid很簡單,在表4中查詢。同窗的信息用inner join聯表1查詢實現。
SELECT * FROM study.dbo.Student as t1 inner join (select Student.SId from Student left join study.dbo.SC on Student.SId=SC.SId group by Student.SId having COUNT(SC.CId)!=(select count(*) from study.dbo.Course)) as t2 on t1.SId=t2.SId