MySQL计算降雨量

时间:2013-05-10 13:02:23

标签: php mysql

我需要MySQL查询的帮助。基本上是为了简化它:

我有一张桌子上有来自气候变化的气象资料。其中一个测量参数是降雨量。我已经设法将计算结果放在一个表格中,其中有一列有日(2月1日,2月2日,2月3日等)和第二列,它给出了该特定日的每日降雨量(0,3.5,14.2等)。 )。

现在我想做的是计算最长的干燥和最长的潮湿时期。换句话说,连续几天降雨量为0的最长时期,湿期是完全相反的 - 大多数连续的“非零”天。

在我想要的输出中 - 期间的天数,开始日期和结束日期。所以基本上两个变量,比如说dry_count,dry_date,然后我会转换成输出,例如:“天数:dry_count,dry_date”。

我最初将它作为两个变量(dry_start和dry_end),但是没有用,因为如果有两个例子,例如存在相同的最长周期,我会想要它,例如。 2月3日 - 2月5日,3月8日 - 3月11日 - 所以日期需要最后保存为一个变量,如果它不为空,那么它将添加一个逗号和另一个句号。

我尝试了各种各样的东西,但没有成功。数据是从MySQL数据库的PHP站点上提取的,所以我得到的结果是一行一行的。有什么帮助吗?我希望我解释好了。

3 个答案:

答案 0 :(得分:2)

如果我理解正确的话,你会尝试将关于潮湿时期和干燥时期的新数据保存回行中,以备日后使用?

我认为这是因为随着每个新的一天被添加,很容易重新计算....或者因为数据正在移动到其他地方?

无论如何,如果是这种情况,那么你可以采用的方法就是有两个新列:'wet_count'和“dry_count”。计算每一行。如果行的湿/干值与前一天,然后递增该值。如果没有,则将值归零并将适当的值设置为新值。如下:

day       rainfall    wet_count    dry_count
Feb 1     1           1            0
Feb 2     0.5         2            0
Feb 3     0.75        3            0
Feb 4     0           0            1
Feb 5     0           0            2
Feb 6     0           0            3
Feb 7     0.5         1            0
Feb 8     1.25        2            0
Feb 9     1.5         3            0
Feb 10    3.5         4            0
Feb 11    4.5         5            0

然后你可以简单地从表格中拉出最大值,回到该日期之前该列中的前1位,然后你就拥有了“最大的时期”和“当它开始时”。

在每个新的一天的数据中,您只需要计算前一天的数据,然后运行两个非常简单的数据库搜索以获得新的“最大期限”。

更具体地说 - 你拉出'wet_count'的明确值,按降序排序,只取第一个答案。您在数据库中执行选择,其中所有wet_count =最大值或1.并且您获得与该特定值匹配的潮湿期数加上可能的开始日期。紧接最大值之前的1将是开始日期。

答案 1 :(得分:1)

我认为相关子查询为MySQL提供了这类问题的最佳方法。这个想法是在没有下雨的一天之后找到第一天下雨,并将其用于分组目的。然后该组的最小值和最大值提供干咒的边界。

这是一个想法:

select min(date) as FirstDate, max(date) as LastDate,
       (max(date) - min(date) + 1) as DrySpellDays
from (select t.*,
             (select date
              from t t2
              where t2.rainfall > 0 and
                    t2.date > t.date
              order by t2.date desc
              limit 1
             ) as NextRainDate
      from t
      where t.rainfall = 0
     ) t
group by NextRainDate

连续潮湿天数的计算遵循相同的结构,但逻辑相反:

select min(date) as FirstDate, max(date) as LastDate,
       (max(date) - min(date) + 1) as DrySpellDays,
       sum(t.rainfall) as TotalRainFall
from (select t.*,
             (select date
              from t t2
              where t2.rainfall = 0 and
                    t2.date > t.date
              order by t2.date desc
              limit 1
             ) as NextDryDate
      from t
      where t.rainfall > 0
     ) t
group by NextDryDate

答案 2 :(得分:0)

这是一个PHP未经优化的尝试。注意:这是未经测试的,我只是在这里输入,没有任何东西可以测试,没有纸张重新考虑这个做得更好,所以可能有很多改进。

$dry_date = NULL;
$dry_length = 0;
$wet_date = NULL;
$wet_length = 0;

$current_date = NULL;
$current_length = 0;

$dry_flip = false;
$wet_flip = false;
// assume you get "select date, rainfall from rainfalltable"
while($row = mysqli_fetch_array($result)) {
    // if rainfall is zero we do dry_day calculation
    if ($row['rainfall'] == 0) {
        // two options here - we already started counting or this is a new streak of dry days
        if ($dry_flip) {
            // if we already started, it's simple
            $current_length = $current_length +1;
        } else {
            // if we didn't start counting, let's reset the counter. 
            if ($wet_flip) {
            // First check the wet status - maybe we were counting it so let's save
                $wet_flip = false;
                if ($current_length > $wet_length) {
                    // since we got the longer streak, we update wet status
                    $wet_date = $current_date;
                    $wet_length = $current_length;
                }
                $current_date = NULL;
                $current_length = 0;
            }
            $current_length = $current_length + 1;      
            // One more thing to do         
            if ($current_length == 1) {
                $current_date = $row['date'];
            }
        }

        } else {
        // two options here - we already started counting or this is a new streak of dry days
        if ($wet_flip) {
            // if we already started, it's simple
            $current_length = $current_length +1;
        } else {
            // if we didn't start counting, let's reset the counter. 
            if ($dry_flip) {
            // First check the wet status - maybe we were counting it so let's save
                $dry_flip = false;
                if ($current_length > $wet_length) {
                    // since we got the longer streak, we update wet status
                    $dry_date = $current_date;
                    $dry_length = $current_length;
                }
                $current_date = NULL;
                $current_length = 0;
            }
            $current_length = $current_length + 1;      
            // One more thing to do         
            if ($current_length == 1) {
                $current_date = $row['date'];
            }
        }
    }


}