一 引言
上一篇??Mysql 排序查詢第N項(xiàng) / 前N項(xiàng)(三種方法)已經(jīng)總結(jié)了取前N項(xiàng)和倒數(shù)前N項(xiàng)的問(wèn)題垮庐,這一篇主要解決分組后查詢前N項(xiàng)/第N項(xiàng)問(wèn)題
例如:查詢每個(gè)員工最高薪資/每個(gè)員工第二薪資/每個(gè)員工最低薪資/各個(gè)品類銷量前十的商品
二 Group By 的作用
說(shuō)到分組,一般離不開group by語(yǔ)句淘正。所以我們先看看group by到底有什么作用
1. group by直接使用,不搭配聚合函數(shù)(sum,average,count等)绒窑,結(jié)果是取出每個(gè)分類字段的第一條記錄(這里的分類字段是emp_no)
2. 搭配聚合函數(shù)(sum,average,count等)阁猜,結(jié)果是根據(jù)分類字段進(jìn)行加總、平均锦援、計(jì)數(shù)
三?每個(gè)員工的最高工資和最低工資
四 每個(gè)員工的第二高工資
1. 為什么不能用 group by+ order by +limit
因?yàn)? limit 1,1 只能取出整個(gè)表的第二行剥悟,不能分組取各個(gè)組的第二行
2. 排名法
其實(shí)就是Mysql 排序查詢第N項(xiàng) / 前N項(xiàng)(三種方法)里面的排名法灵寺。原理:假如 a 排第10,意味著前面有9個(gè)數(shù)比a大懦胞,有10個(gè)數(shù)大于等于a替久,?求某個(gè)數(shù)的排名就是求前面有幾個(gè)數(shù)大于等于這個(gè)數(shù)
思路:重復(fù)用salaries表凉泄,命名為s1,s2躏尉。用where語(yǔ)句s1.salary<=s2.salary篩選出所有大于等于s1.salary的s2.salary。然后統(tǒng)計(jì)每個(gè)s1.salary有多少個(gè)s2.salary大于等于它后众,就能得到每個(gè)s1.salary的排名
那么分組取第N項(xiàng)的排名法和上文有什么不一樣呢胀糜。區(qū)別在于:排序查詢前N項(xiàng)時(shí)颅拦,s1.salary<=s2.salary篩選出的是全表所有薪資中大于等于s1.salary的s2.salary。而我們要的是員工和自己的其他工資對(duì)比教藻,是在員工自己的歷史工資里面篩選距帅,而不是在全表所有員工薪資里面篩選。轉(zhuǎn)化為mysql語(yǔ)言就是括堤,要在以員工編號(hào)為依據(jù)的分組里面篩選碌秸。因此,這里的排名法多了一個(gè)條件??s1.emp_no = s2.emp_no悄窃。
2.1 第一步
重復(fù)使用salaries表讥电,分別命名為s1,s2。用 where s1.emp_no = s2.emp_no 將兩個(gè)相同的表連接
保證只有員工編號(hào)相同的s1.salary 和s2.salary才能匹配上轧抗。
2.2 第二步
增加where條件:s1.salary<=s2.salary恩敌。 篩選出所有小于等于s1.salary 的 s2.salary?
2.3 第三步?
統(tǒng)計(jì)每個(gè)s1.salary有幾個(gè)小于等于它的s2.salary,也就是s1.salary的排名
2.4 完整代碼
不用group by 横媚。?
五? 每個(gè)員工的倒數(shù)第二工資
方法和上面一樣纠炮,只是把s1.salary<=s2.salary 換成s1.salary >= s2.salary
不用group by?
六? 每個(gè)員工最低工資減去第二低工資
思路:查出每個(gè)員工的最低工資,作為臨時(shí)表a,查出每個(gè)員工的第二低工資作為臨時(shí)表b灯蝴。將a,b作為from 的子查詢恢口,用where 語(yǔ)句關(guān)聯(lián)兩個(gè)表