【问题标题】:PHP function to find the median of a column in MySQLPHP函数在MySQL中查找列的中位数
【发布时间】:2014-01-02 01:09:13
【问题描述】:

我有一个数据库 db 和一个表 Table

看起来有点像:

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:它也应该适用于许多重复的情况。

【问题讨论】:

  • 如果你只是想在php中做,只要把所有的值拉出来,放入一个数组中,对数组进行排序,找到中位数。
  • 会不会很慢?排序然后找到中间值?
  • 这肯定取决于数据集。我只是根据现在那里的情况。
  • 这只是一个例子,我实际上有一个庞大的数据集。我会修改问题。谢谢!
  • 这只是一个想法,但是您可以先通过sql计算数据的大小。然后查询数据(排序),但选择计数行的 1/2,所以你在中间点,然后只是最后一行数据?

标签: php mysql sql median


【解决方案1】:

只是为了好玩,我想我尝试在 MySQL 中完成这一切,这里是 sqlFiddle

SELECT 
  CASE 
  WHEN MOD((select count(*) as count from t),2)=1 THEN
      (select val from
           (select @row:=@row+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:=@row+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:=@row+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 替换为您的表名,不要更改t1。 此外,如果表没有行,它将返回 NULL 作为中位数。

这个查询可以进一步简化为以下(sqlFiddle

SELECT @rowCount:=(select count(*) as count from t) AS rowcount,
      (select AVG(val) from
           (select @row:=@row+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 列放在那里是因为我不想像以前的查询那样从 t 中多次计数。

【讨论】:

  • 这会返回什么?我是 MySQL 的新手,我很难将它转换为 PHP。
  • 好的,知道了!将结果转换为数组,并将第一个元素作为我的返回输出。
  • 您可能更喜欢第二个查询,因为它的长度大约是第一个的一半。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-28
  • 2017-03-27
  • 2011-03-25
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
相关资源
最近更新 更多