員工薪水中位數java
題目描述:數組
預期答案:函數
解法1blog
既然是求解中位數,咱們首先想到的是根據中位數的定義進行求解:奇數個數字時,中位數是中間的數字;偶數個數字時,中位數中間兩個數的均值。本題不進行求解均值,而是將兩個中位數所有顯示。排序
根據定義,爲了查詢中位數,咱們須要知道3點信息:it
總數是奇數個仍是偶數個class
待查找數字總數效率
每一個數字的排序編號變量
前兩點信息在MySQL中很是簡單,只需簡單的count計數便可,而排序編號則須要藉助輔助方法。在MySQL8.0以上版本引入了窗口函數後很是容易實現,但之前的版本則僅可經過自定義變量的方式得到排序值。這裏如何對員工薪水進行分組排序再也不展開原理
在有了排名和數字總數以後,如何判斷是中位數呢?這裏計數字總數爲N,則
N爲奇數,中位數排序編號是(N+1)/2=N/2+0.5
N爲偶數,中位數排序編號是N/2和N/2+1
進一步地,N爲奇數和N爲偶數是互斥的,求解出的中位數排序編號也是互斥的,也就是說3個排序編號不會同時取得整數,從而能夠不加區分的直接判斷便可。
查詢SQL語句:
SELECT e1.Id, e1.Company, e1.Salary FROM (SELECT Id, Company, Salary, @rnk:=if(@pre=Company, @rnk+1, 1) rnk, @pre:=Company FROM Employee, (SELECT @rnk:=0, @pre:=null)init ORDER by Company, Salary, Id)e1 JOIN (SELECT Company, count(*) cnt FROM Employee GROUP by Company) e2 using(Company) WHERE e1.rnk in (cnt/2+0.5, cnt/2, cnt/2+1)
查詢效率:
解法2
除了根據中位數的排序編號來定位其位置,實際上還能夠換種思路但仍然是在其排序編號上作文章:若是一個數是中位數,那麼就意味着正序和逆序時其位置是一致的:更嚴謹的說,奇數個數字是正逆序排序一致,偶數個數字時,兩中位數順序要互換一下,也就是相差爲1。進而,咱們發現不管數字總數是奇數仍是偶數,中位數的正逆排序相差要麼爲0,要麼爲1。根據這一性質,咱們分別實現正逆兩遍排序,而後判斷數字的排序編號便可。
查詢SQL語句:
SELECT e1.Id, e1.Company, e1.Salary FROM (SELECT Id, Company, Salary, @rnk:=if(@pre=Company, @rnk+1, 1) rnk, @pre:=Company FROM Employee, (SELECT @rnk:=0, @pre:=null)init ORDER by Company, Salary, Id)e1 JOIN (SELECT Id, Company, Salary, @rnk:=if(@pre=Company, @rnk+1, 1) rnk, @pre:=Company FROM Employee, (SELECT @rnk:=0, @pre:=null)init ORDER by Company, Salary DESC, Id DESC)e2 on e1.Id=e2.Id WHERE abs(e1.rnk - e2.rnk)<=1
查詢效率:
解法3
前2種解法都是根據中位數的定義在數字排序編號上做文章,下面是一個對中位數性質更深的理解(摘抄自官方題解)
根據定義,咱們來找一下 [1, 3, 2] 的中位數。首先 1 不是中位數,由於這個數組有三個元素,卻有兩個元素 (3,2) 大於 1。3 也不是中位數,由於有兩個元素小於 3。對於 2 來講,大於 2 和 小於 2 的元素數量是相等的,所以 2 是當前數組的中位數。當數組長度爲 偶數,且元素惟一時,中位數等於排序後 中間兩個數 的平均值。對這兩個數來講,大於當前數的數值個數跟小於當前數的數值個數絕對值之差爲 1,剛好等於這個數出現的頻率。
結論:無論數組長度是奇是偶,也無論元素是否惟一,中位數出現的頻率必定大於等於 大於它的數 和 小於它的數 的絕對值之差。
好吧,力扣的官方題解讀起來老是這麼生澀。不過細品之下,咱們仍是能夠發現這個結論是對的。【好像說了句廢話】
根據中位數的這一性質,能夠寫出以下查詢語句:
SELECT e1.Id, e1.Company, e1.Salary FROM Employee e1, Employee e2 WHERE e1.Company = e2.Company GROUP BY e1.Company , e1.Salary HAVING SUM(e1.Salary = e2.Salary) >= ABS(SUM(SIGN(e1.Salary - e2.Salary))) ORDER BY e1.Id
查詢效率:
實際上,雖然3種解法均爲兩表關聯,但因爲解法3中涉及到相對更爲複雜的計算,其效率居然要比解法1和解法2中低太多。
因此,不妨想一想奧卡姆剃刀原理,大道至簡、大巧不工、簡單之美!