对于每一行,计算MySQL

时间:2015-11-11 00:24:44

标签: php mysql csv

我需要使用PHP脚本计算我在csv文件中从Google财经导入的股票价格的平均值和标准差。我可以将这些csv文件导入mysql到不同的表中。我打算将每个库存存储在一个单独的表中,以使其开始时不那么复杂。

在电子表格中,计算最后n行的运行平均值相当容易。但是,一旦我导入到MySQL,我就会对如何计算从第20行开始的每行的最后20行的平均值感到震惊(显然知之甚少)。

从Google财经导入时,我的表格结构如下所示:

+-------------+---------+
|     id      |  close  |
+-------------+---------+
| a1447128000 | 1353.5  |
| 1           | 1356.2  |
| 2           | 1352.65 |
| 3           | 1355.65 |
| 4           | 1354.2  |
| 5           | 1356    |
| 6           | 1351    |
| 7           | 1352.5  |
| 8           | 1350    |
| 9           | 1349.3  |
| 10          | 1343.6  |
| 11          | 1342.4  |
| 12          | 1340.7  |
| 13          | 1338.5  |
| 14          | 1340.5  |
| 15          | 1338.5  |
| 16          | 1340    |
| 17          | 1335.25 |
| 18          | 1340.5  |
| 19          | 1341    |
| 20          | 1338.95 |
| 21          | 1334    |
| 22          | 1326.5  |
| 23          | 1320.1  |
| 24          | 1318    |
+-------------+---------+

我正在尝试实现这样的输出:

+-------------+---------+-----------+--------------------+
|     id      |  close  |  average  | standard deviation |
+-------------+---------+-----------+--------------------+
| a1447128000 | 1353.5  |           |                    |
| 1           | 1356.2  |           |                    |
| 2           | 1352.65 |           |                    |
| 3           | 1355.65 |           |                    |
| 4           | 1354.2  |           |                    |
| 5           | 1356    |           |                    |
| 6           | 1351    |           |                    |
| 7           | 1352.5  |           |                    |
| 8           | 1350    |           |                    |
| 9           | 1349.3  |           |                    |
| 10          | 1343.6  |           |                    |
| 11          | 1342.4  |           |                    |
| 12          | 1340.7  |           |                    |
| 13          | 1338.5  |           |                    |
| 14          | 1340.5  |           |                    |
| 15          | 1338.5  |           |                    |
| 16          | 1340    |           |                    |
| 17          | 1335.25 |           |                    |
| 18          | 1340.5  |           |                    |
| 19          | 1341    | 1346.5975 | 6.885664002        |
| 20          | 1338.95 | 1345.87   | 6.886588415        |
| 21          | 1334    | 1344.76   | 6.921155973        |
| 22          | 1326.5  | 1343.4525 | 7.729917124        |
| 23          | 1320.1  | 1341.675  | 8.7418605          |
| 24          | 1318    | 1339.865  | 9.660513703        |
+-------------+---------+-----------+--------------------+

正如您所注意到的那样,对于行ID 19,平均值将是最后20行。对于行ID 20,平均值将是最后20行......依此类推。

我甚至想知道是否可以使用php的foreach循环遍历每一行并获得最后20行的平均值但是当我尝试时我完全迷失了。

我无法在此处获得任何线索(在MySQL或PHP中)。如果有任何关于如何解决此问题的建议,将不胜感激。

4 个答案:

答案 0 :(得分:2)

下面的代码粗略地显示了你可以做什么

$averages = array();
while($row = $result->fetch_assoc())
{
    $sum = 0;
    $arraySize = array_push($averages,$row['close']);

    if($arraySize > 20)
    {
        array_shift($averages)
    }

    foreach($averages as $value)
    {
        $sum += $value;
    }
    $average = $sum / $arraySize
}

从代码开头的空数组开始,在MySQL结果循环的每次迭代中使用array_push,它还会在将值添加到数组后返回数组的大小。然后检查这个值,如果它大于20,你使用array_shift将所有内容向下移1,从而删除第一个值

如果你不想计算数组中值的数量是否小于20时,只需将foreach包裹起来,然后在if语句中显示该行

答案 1 :(得分:1)

page-whatever.php

答案 2 :(得分:1)

不确定你将如何显示平均值,但这应该有效。

$values = array();
$sum = 0;
$i = 0;
while($row = $result->fetch_assoc())
{
    $values[] = $row['close'];
    $sum += $row['close'];
    if($i > 19)
    {
        $sum -= $values[$i - 20];
        $row['average'] = $sum/20;
    }
}

答案 3 :(得分:1)

以下是适合我的完整代码。感谢@ Memor-X,@origenes和@Terminus,因为这段代码是使用他们的回复开发的。我甚至使用相同的逻辑计算标准偏差。

$averages = array();

while($row = $result->fetch_assoc())
{
      $sum = 0;
    $arraySize = array_push($averages,$row['close']);

    if($arraySize > 20)
    {
        array_shift($averages);
    }

if($arraySize > 19) {

    $sum = array_sum($averages);

    $average = $sum /20;
    echo "average: " .$average ."<br/>";
    }
    $sumOfDiff =0;
if($arraySize > 19) {
    foreach($averages as $valueitem)
    {
        $sumOfDiff += ($valueitem - $average)*($valueitem - $average);
    }
    $variance = $sumOfDiff/20;
    $stddev = sqrt($variance);
    $upperband = $average + ($stddev *2);
    $lowerband = $average - ($stddev *2);
    echo "variance: " .$variance."<br/>";
    echo "standard deviation: " .$stddev ."<br/>";

    }

}