2013-12-14 22 views
1

我有一個數據庫,DB並在它的表,表PHP函數來查找列的中位數在MySQL

它看起來有點像:

id | val 
-------- 
1 | 45 
2 | 35 
3 | 23 
4 | 49 
5 | 67 
6 | 12 
7 | 0 
8 | 87 
9 | 46 

(。這僅僅是一個示例數據集中的實際數據集是巨大的,我需要工作在最短的時間可能)

我需要找到列的中位數val。其實我需要一個PHP函數多次使用。

類似的問題確實存在:Simple way to calculate median with MySQL

我在這個問題上嘗試了一些答案,他們沒有爲我工作。接受的答案不起作用,因爲它只用於舊版本的SQL。 PS:它也應該在許多重複的情況下工作。

+0

如果你只是想在PHP中做到這一點,只需拔出所有的值,放入一個數組,排序數組,找到中位數。 – user602525

+0

這不會很慢嗎?排序,然後找到中間值? – Ranveer

+0

那麼,這取決於肯定的數據集。我只是基於現在的情況而定。 – user602525

回答

0

只是爲了好玩,我想我嘗試做這一切在MySQL中,這裏的sqlFiddle

SELECT 
    CASE 
    WHEN MOD((select count(*) as count from t),2)=1 THEN 
     (select val from 
      (select @row:[email protected]+1 as row,val 
      from t,(select @row:=0)r 
      order by val)t1 
     where t1.row = CEIL((select count(*) as count from t)/2) 
    ) 
    ELSE 
     ((select val from 
      (select @row:[email protected]+1 as row,val 
      from t,(select @row:=0)r 
      order by val)t1 
     where t1.row = (select count(*) as count from t)/2)+ 
     (select val from 
      (select @row:[email protected]+1 as row,val 
      from t,(select @row:=0)r 
      order by val)t1 
     where t1.row = ((select count(*) as count from t)/2)+1))/2 
    END AS median 

只需用表名稱取代t OCCURENCES,不改變t1。 另外,如果表中沒有行,它將返回NULL作爲中位數。

該查詢可以進一步降低到下述(sqlFiddle

SELECT @rowCount:=(select count(*) as count from t) AS rowcount, 
     (select AVG(val) from 
      (select @row:[email protected]+1 as row,val 
      from t,(select @row:=0)r 
      order by val)t1 
     where t1.row IN (FLOOR((@rowCount+1)/2), 
         CEIL((@rowCount+1)/2) 
         ) 
    ) as Median 

它會返回2列,一個rowcount柱和median柱。我把rowcount列放在那裏,因爲我不想像以前的查詢那樣從多次計數。

+0

這是什麼回報?我是MySQL的新手,我很難將其轉換爲PHP。 – Ranveer

+0

好吧!將結果轉換爲一個數組,並將第一個元素作爲我的返回輸出。 – Ranveer

+0

您可能更喜歡第二個查詢,因爲它大約是第一個查詢的一半長度。 –