sql多表查詢之三:子查詢IN

關於使用子查詢IN,給你們一個小忠告:子查詢IN適合外結果集大,子查詢結果集小的狀況,千萬不能濫用子查詢IN,您必定要保證子查詢所返回的結果集儘可能的小,哪怕你的SQL返回記錄數只有1條,若是你使用到了子查詢IN,而你的子查詢返回10000條,那速度會受到很大影響呢

你們都領會過使用不等鏈接進行庫存計算的神妙了吧,有沒有應用到本身的學習與工做中去呢?今天咱們上第三盆菜,子查詢,有什麼建議或意見也歡迎你們多多留言討論啦!sql

什麼?你尚未看到不等鏈接,那麼點點這裏吧 sql多表查詢之二:不等鏈接
今天咱們要介紹的是子查詢
子查詢你們應該都不陌生啦,在不少地方可使用到的
首先咱們來總結一下 SQL子查詢能夠用在哪些地方
子查詢的位置
Select <子查詢> from <子查詢> where <子查詢>
 
 Insert table (columns) <子查詢>
 
  Delete table from <子查詢> where <子查詢>
 
Update table from <子查詢> where <子查詢>
 
   那麼,大家知道子查詢的關鍵字有哪些嗎?
IN
EXISTS
對,就這兩個,是否是很簡單呢
 
但是,要把子查詢用好,可不是一件這麼容易的事情
 
今天咱們來介紹子查詢IN
IN 關鍵字使您得以選擇與列表中的任意一個值匹配的行
太抽象了是嗎,咱們仍是來看看實例吧:
這是一個數據模型
請用SQL來實現如下問題
1.顯示成績所有及格的學生名單
 
2.顯示各班總成績最好的學生名單
 
3.顯示各班各課目成績前3位學生的成績
 
第一題應該很簡單,其實有不少種寫法
首先,如何獲得及格的學生呢?
select 學號 from 成績 where 成績>=60
而後,這樣只能獲得學號呀,因此,咱們須要:
select * from 學生 where 學號 in (select 學號 from 成績 where 成績>=60)
換一個寫法可不能夠呢?
select * from 學生 where 學號 not in (select 學號 from 成績 where 成績<60)
固然能夠,想一想哪一種效率高,班上是及格的學生多仍是不及格的學生多呢?
若是及格的學生多,那麼select 學號 from 成績 where 成績<60,是否是返回的數據量更小呢?固然效率就高一些!
 
第二題,顯示各班總成績最好的學生名單
咱們先把問題簡單化,獲得某一個班成績最好的學生
select max(成績) from 成績 where 班級=XX
這個容易吧!
各班成績最好的呢?
select 學號 from 成績 a where 成績=(select max(成績) from 成績 where 班級=a.班級
把成績表A與子查詢經過班級關聯,用成績作條件,搞定!
學生名單
select * from 學生 where 學號 in (
       select 學號 from 成績 a where 成績=(select max(成績) from 成績 where 班級=a.班級)
)
也不復雜吧
 
第三題,顯示各班各課目成績前3位學生的成績
跟第二題有點象吧,但是,你們注意,第二題只取每一個班的第一名,咱們能夠用MAX,這裏,彷佛用不了了吧….
怎麼辦呢
其實很簡單,在第二題中,咱們的成績是用=,而這題中,咱們的成績用IN不就能夠了嗎?
select * from 成績 a where 成績 in(select top 3 成績 from 成績 where 班級=a.班級 and 課目=a.課目order by 成績.成績 desc)
不過,有沒有發現小漏洞呢,若是我有兩個第三名的成績同樣,會返回幾條記錄呢,留給你們想一想吧:)
 
關於使用子查詢IN,給你們一個小忠告:子查詢適合外結果集大,子查詢結果集小的狀況,千萬不能濫用子查詢IN,您必定要保證子查詢所返回的結果集儘可能的小,哪怕你的SQL返回記錄數只有1條,若是你使用到了子查詢,而你的子查詢返回10000條,那速度會受到很大影響呢,那天你的SQLSERVER當機了,可千萬不要來找我麻煩呀,哈哈
還有,其實第二題中的子查詢與外面的表進行關聯XX=外表.XX,通常狀況下,咱們是不太贊同這樣使用的,同時會存在性能問題
那麼,會不會更好的解決方案呢?下期四夕將介紹子查詢中應用面更廣的 EXISTS,靜請關注哦!
相關文章
相關標籤/搜索