sql 經典查詢50題 思路(一)

由於須要提升一下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
相關文章
相關標籤/搜索