記一個簡單的sql題:思維擴散

Skyline7發表於2018-03-03

題目很簡單:(一定會有人說治好了多年的頸椎)

記一個簡單的sql題:思維擴散

這麼簡單的題,於是1分鐘不到我們有了解法1

  • 解法1: 子查詢 + not in
select distinct t.name from student t where t.name not in(select t.name from student t where t.score <= 80) 
複製程式碼

這種寫法比較容易想到,先查至少有一門課程小於80,然後not in ,就是查詢所有課程都大於80。但是比較冗餘,也沒啥技術含量,關鍵這種如果資料量多效率也不好,於是我們有了解法2。

  • 解法2: 子查詢 + group by + having + not in
select t.name from student t group by t.name having t.name not in(select t.name from student t where t.score <= 80)
複製程式碼

這種寫法貌似和上面那種差別不大,只是加了一個分組而已? 但是,真的是這樣嗎,我們發現,這種寫法不需要加去重,因為已經分組了。總的來說,這種寫法略優於解法1,但還是老毛病,子查詢需要查詢2次,效率不高,於是,我們有了解法3.

  • 解法3:group by + having + count
select t.name from student t group by t.name having count(t.score) = sum(case when t.score > 80 then 1 else 0 end)
複製程式碼

咳咳,這種寫法就比較炫技了,又是分組又是聚合函式的。但是也是一種思路嘛,至於效率的話,和第二種半斤八兩,只能說,這個逼裝的挺6。難道沒有一種不需要子查詢的麼? 讓我們看看解法4.

  • 解法4: group by + having + min
select t.name from student t group by t.name having min(t.score) > 80
複製程式碼

高手過招,一招制敵。用這句話形容解法4再合適不過了,抓住了題目的關鍵點,合理的使用min()聚合函式。應該是這題的最優解。

以上就是我對這道題的思考,如果大家還有什麼其他的解法,見解, 或者我的解法有不足之處,歡迎評論區留言討論。

相關文章