PHP/MySQL基于Array内容的平均值


PHP/MySQL Average based on contents of Array

我有以下数组:

array(
    a => 6.75,
    b => 5.45,
    c => 8.76,
    d => 7.76,
    e => 8.16,
    f => 2.76,
    g => 4.67,
    h => 9.01,
    i => 5.42,
)

我希望实现的是averagetop quartile

本质上,我需要按descending顺序排列数组,然后计算top quartile将是什么(即9(数组中的元素数量)x 25% = 2.25舍入到2,因此需要平均前两个数字)。

我要找的就是这个人。

我正在努力弄清楚如何实现这一点,是否最好在PHP内或通过查询MySQL数据库。

欢迎任何意见、反馈和建议。

在MySQL中很难做到这一点,因为你不能直接使用变量LIMIT

但是,在那里做肯定是最有效的,而不是在只需要一部分数据时将所有数据传输到PHP。

所以,考虑到这一点,试试这个算法:
  • SELECT COUNT(*)从您的表中获取行数
  • 将行数除以4,称为$quartile_count
  • 现在你需要一个嵌套查询:

    SELECT AVG(`column_name`)
    FROM (
        SELECT `column_name`
        FROM `table_name`
        ORDER BY `column_name` DESC
        LIMIT $quartile_count
    ) `tmp`
    

    这是因为LIMIT必须在聚合AVG函数之前先应用。

这在PHP中很容易做到:

$array = array(
a => 6.75,
b => 5.45,
c => 8.76,
d => 7.76,
e => 8.16,
f => 2.76,
g => 4.67,
h => 9.01,
i => 5.42,
);
arsort($array); // Order the array in descending order
$top_quartile = floor(count($array)/4); // Calculate top quartile
$array = array_slice($array, 0, $top_quartile); // Keep only the top quartile values
$total = 0;
foreach($array as $value) {
    $total += $value;
}
$average = $total/$top_quartile;
echo $average;
$a = array(
    'a' => 6.75,
    'b' => 5.45,
    'c' => 8.76,
    'd' => 7.76,
    'e' => 8.16,
    'f' => 2.76,
    'g' => 4.67,
    'h' => 9.01,
    'i' => 5.42,
);
rsort($a);
$sum = 0;
for($i = 0; $i < count($a) / 4; ++$i){
    $sum += $a[$i];
}
$result = $sum / $i;
echo $result;

在一段SQL中完成:-

SELECT AVG(some_column)
FROM
(
    SELECT some_column, @seq:=@seq+1 AS seq
    FROM
    (
        SELECT some_column
        FROM some_values
        ORDER BY some_column DESC
    ) sub0
    CROSS JOIN (SELECT @seq:=0) sub1
) sub2
CROSS JOIN
(
    SELECT COUNT(*) AS all_count
    FROM some_values
) sub3
WHERE sub3.all_count / 4 > sub2.seq

这有一个子查询,以降序获取行,然后添加一个序列号,然后交叉连接的结果与子查询,获得记录的总数,有一个WHERE子句,以消除除前四分之一,然后使用AVG()获得平均值。

更多的是出于兴趣而不是作为一个实际的解决方案,因为我怀疑它会表现不佳。只有当你需要它作为数据源,必须是一个单一的查询时才真正有用。

这是您的问题的完整代码。

$rs = mysql_query("select count(column name) as total from table");
$result = mysql_fetch_row($rs);
$avg = floor($result[0]/4);
$rs = mysql_query("select column name from table order by column name desc limit 0,".$avg);
$total = 0;
while($result = mysql_fetch_array($rs))
{
     $total += $result['column name'];
}
echo $total/mysql_num_rows($rs);