1. 程式人生 > 實用技巧 >一個SQL查詢出每門課程的成績都大於80的學生姓名

一個SQL查詢出每門課程的成績都大於80的學生姓名

name kecheng fenshu
張三 語文 81
張三 數學 75
李四 語文 76
李四 數學 90
王五 語文 81
王五 數學 100
王五 英語 90

方法一:

  思路:採用逆向思維想想。。。。。。求三門成績都大於80的人,也可以是使先查出有成績小於80 的人,再除去這些人不就是三門成績都大於80的人了麼? 以前學過的數學邏輯逆向思維還真是有用的阿!!

  具體辦法:先掃描表,查出有成績小於80的人的姓名,然後再次掃描表,用not in 或not exists 方法。

  點評:此方法採用逆向思維,能快速寫出高效且簡單的 SQL語句。

//not in 
SELECT DISTINCT A.name FROM Student A 
WHERE A.name not in(
SELECT Distinct S.name FROM Student S WHERE S.score <80)

//not exists

SELECT DISTINCT A.name From Student A  
where not exists (SELECT 1 From Student S Where  S.score <80 AND S.name =A.name)

/*exists 詳解
取出 外表第一條資料 ,然後與內表  根據連線條件 ,
形成一條或多條資料,判斷這些生成的資料中是否存在
或者是不存在符合where條件的 。結果為ture的那條外表
記錄舊被查詢出來!

例項過程: 取出外表的第一條記錄, 
和內表通過姓名條件連線,這時候產生2兩記錄,
根據 not exists是判斷不存在。 條件是 score<80 .
而這兩條記錄存在一條記錄小於80,所以於not exists 不符合,
該條記錄不被查出。
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

方法二:

SELECT S.name
FROM Student S
GROUP BY S.name
Having MIN(S.score)>=80
  • 1
  • 2
  • 3
  • 4

方法三:

  思路:如果能獲得一張表,由學生姓名,語文成績,數學成績,英語成績的表,剩下的就是在WHERE條件中篩選及可以獲得想要的結果。

  具體辦法:通過自連線的辦法,以“姓名”為連線條件,自連線三次,便可以獲得包含又姓名和三門課程成績的資料行。雖然可以得到想要的資料列。但會有很多冗餘重複列!

  點評:此方法是根據題目,依題解題,中規中矩! 不過多張表連線非常耗費時間。而且SQL語句也比較複雜,需要注意事項很多。

SELECT  D.name  FROM (
SELECT  S.name,S.score AS ITEM1,S1.score AS ITEM2,S2.score AS ITEM3
FROM Student S 
inner join Student S1 on S.name = S1.name and S.course <> S1.course
inner join Student S2 on S.name = S2.name and S.course <> S2.course
WHERE S.score>=80 and S1.score>=80 and S2.score>=80
) D 
GROUP BY D.name 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

參考文章:http://www.cnblogs.com/hongyan5682/p/4816444.html