2

MySQL クエリについてサポートが必要です。基本的に単純化するには:

気象台からの気象データを含むテーブルがあります。測定パラメータの 1 つは降水量です。1 つの列に日付 (2 月 1 日、2 月 2 日、2 月 3 日など) と、その特定の日の 1 日あたりの降雨量 (0、3.5、14.2 など) を示す 2 番目の列があるフォームに計算を取得することができました。 )。

次にやりたいことは、最長乾燥期間と最長湿潤期間を計算することです。言い換えれば、連続した日に降水量が 0 になる最も長い期間であり、湿潤期間は正反対で、最も連続した「ゼロでない」日です。

必要な出力には、期間の日数、開始日、終了日があります。したがって、基本的に 2 つの変数、dry_count、dry_date としましょう。これを、「日数: dry_count、dry_date」のような出力に変換します。

最初は2つの変数(dry_startとdry_end)として持っていましたが、それはうまくいきませんでした. 2 月 3 日 - 2 月 5 日、3 月 8 日 - 3 月 11 日 - したがって、日付は最後に 1 つの変数として保存する必要があり、それが null でない場合は、コンマと他のピリオドが追加されます。

いろいろ試しましたがうまくいきませんでした。データはPHPサイトでMySQLデータベースから抽出されるため、行ごとにwhileステートメントで結果を取得しています。何か助けてください。うまく説明できたと思います。

4

3 に答える 3

2

私の理解が正しければ、雨期と乾期に関するこの新しいデータを行に保存して、後で使用できるようにしようとしているのですか?

これは、新しい日が追加されるたびに簡単に再計算できるようにするためだと思います....またはデータが別の場所に移動しているためですか?

いずれにせよ、これが事実である場合、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 に戻るだけで、「最大期間」と「開始時期」が得られます。

それぞれの新しい日のデータについて、前日と比較して計算するだけで済み、非常に単純なデータベース検索を 2 回実行して、新しい「最大期間」を取得します。

より具体的には、「wet_count」の個別の値を降順に引き出し、最初の回答のみを取得します。all wet_count = その最大、または 1 であるデータベースで選択を行うと、その特定の値に一致するウェット期間の数と、可能な開始日が得られます。最大値の直前の 1 が開始日になります。

于 2013-05-10T13:09:17.470 に答える
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
于 2013-05-10T13:08:39.627 に答える
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'];
            }
        }
    }


}
于 2013-05-10T13:33:47.737 に答える