MYSQL中求每個分組中的最大值
阿新 • • 發佈:2018-11-08
求每個分組中的最大值
問題可參考https://segmentfault.com/q/1010000004138670
mysql> select * from test;
+----+-------+-----+-------+
| id | name | age | class |
+----+-------+-----+-------+
| 1 | wang | 11 | 3 |
| 2 | qiu | 22 | 1 |
| 3 | liu | 42 | 1 |
| 4 | qian | 20 | 2 |
| 5 | zheng | 20 | 2 |
| 6 | li | 33 | 3 |
+----+-------+-----+-------+
問題:如何選出每班年齡最大者?要求返回符合要求的一行
- 嘗試一:
selecet id,name,Max(age),class from test group by class
上面這個寫法是錯誤的,因為
包含group by 的SQL語句,select的列要麼是聚合函式,要麼只能出現在group by 子句中
而id和name不滿足要求,返回的結果會錯位。
- 嘗試二:group by + join方式
select t1.id,name,t1.age,t1.class from test as t1,
(select class ,Max(age)as age from test group by class)as t2
where t1.class= t2.class and t1.age = t2.age
這條語句引用了兩個表(t1 和 t2),語義上相當於內連線(INNER JOIN)。子查詢可以作為一個一次性的檢視(子查詢必須用括號括起來,一般後面接”as 表名”來將子查詢的結果儲存下來 )
- 嘗試三: 對嘗試二進行優化,一般join的時候小表在前,大表在後
select t1.id,name,t1.age,t1.class from
(select Max(age)as age,class from test group by class)as t2
inner join test t1 on t1.age = t2.age and t1.class = t2.class
- 嘗試四:另一種子查詢方式–巢狀子查詢
select t1.id,name,t1.age,t1.class from test t1
where t1.age = (select max(age) from test t2 where t2.class = t1.class)
總結
- 上述嘗試二、三、四均正確,均可以返回最大值有多條情況時的記錄。
- 在SQL語句中,含有子查詢一般比較慢,應該儘量避免使用子查詢,所以嘗試四要比嘗試二、三慢,應該儘量使用嘗試二、三(即join+group by的形式)
關於Group by
在使用分組和聚合函式時,SELET子句中只能存在以下三種元素:
(1)常數
(2)聚合函式
(3)GROUP BY 子句中指定的列名
在 GROUP BY 子句中不能使用列的別名。
GROUP BY 子句結果的顯示是無限的。
只有 SELECT 子句和 HAVING 子句中能夠使用聚合函式,特別是 WHERE 子句中無法使用。
參考連結
https://segmentfault.com/q/1010000004138670
https://segmentfault.com/a/1190000004157112
https://www.jianshu.com/p/47568113fe73