N秒ごとにサンプルをキャプチャするテーブル(MySQL)があります。テーブルには多くの列がありますが、これに関して重要なことは、タイムスタンプ(タイプTIMESTAMP)とカウント(タイプINT)の2つだけです。
私がしたいのは、ある範囲の時間にわたるカウント列の合計と平均を取得することです。たとえば、2秒ごとに記録されたサンプルがありますが、すべてのサンプルの10秒または30秒のウィンドウ内のすべてのサンプルのカウント列の合計が必要です。
データの例を次に示します。
+ --------------------- + ----------------- + | time_stamp |カウント| + --------------------- + ----------------- + | 2010-06-15 23:35:28 | 1 | | 2010-06-15 23:35:30 | 1 | | 2010-06-15 23:35:30 | 1 | | 2010-06-15 23:35:30 | 942 | | 2010-06-15 23:35:30 | 180 | | 2010-06-15 23:35:30 | 4 | | 2010-06-15 23:35:30 | 52 | | 2010-06-15 23:35:30 | 12 | | 2010-06-15 23:35:30 | 1 | | 2010-06-15 23:35:30 | 1 | | 2010-06-15 23:35:33 | 1468 | | 2010-06-15 23:35:33 | 247 | | 2010-06-15 23:35:33 | 1 | | 2010-06-15 23:35:33 | 81 | | 2010-06-15 23:35:33 | 16 | | 2010-06-15 23:35:35 | 1828 | | 2010-06-15 23:35:35 | 214 | | 2010-06-15 23:35:35 | 75 | | 2010-06-15 23:35:35 | 8 | | 2010-06-15 23:35:37 | 1799 | | 2010-06-15 23:35:37 | 24 | | 2010-06-15 23:35:37 | 11 | | 2010-06-15 23:35:37 | 2 | | 2010-06-15 23:35:40 | 575 | | 2010-06-15 23:35:40 | 1 | | 2010-06-17 10:39:35 | 2 | | 2010-06-17 10:39:35 | 2 | | 2010-06-17 10:39:35 | 1 | | 2010-06-17 10:39:35 | 2 | | 2010-06-17 10:39:35 | 1 | | 2010-06-17 10:39:40 | 35 | | 2010-06-17 10:39:40 | 19 | | 2010-06-17 10:39:40 | 37 | | 2010-06-17 10:39:42 | 64 | | 2010-06-17 10:39:42 | 3 | | 2010-06-17 10:39:42 | 31 | | 2010-06-17 10:39:42 | 7 | | 2010-06-17 10:39:42 | 246 | + --------------------- + ----------------- +
(上記のデータに基づいて)希望する出力は次のようになります。
+ --------------------- + ----------------- + | 2010-06-15 23:35:00 | 1 | #これは00〜30秒の範囲の合計です | 2010-06-15 23:35:30 | 7544 | #これは30〜60秒の範囲の合計です。 | 2010-06-17 10:39:35 | 450 | #これは30〜60秒の範囲の合計です。 + --------------------- + ---------- ------- +
私はGROUP BYを使用してこれらの数値を秒単位または分単位で収集しましたが、GROUP BYコマンドが正しく機能するように、分以下または秒の範囲を取得するための構文を理解できていないようです。
主にこのクエリを使用して、このテーブルから別のテーブルにデータを吸い上げます。
ありがとう!
GROUP BY UNIX_TIMESTAMP(time_stamp) DIV 30
または、何らかの理由でそれらを20秒間隔でグループ化したい場合は_DIV 20
_などになります。_GROUP BY
_値の境界を変更するには、次のように使用できます
GROUP BY (UNIX_TIMESTAMP(time_stamp) + r) DIV 30
ここで、r
は、30未満のリテラル非負整数です。したがって、
GROUP BY (UNIX_TIMESTAMP(time_stamp) + 5) DIV 30
hh:mm:05とhh:mm:35の間、およびhh:mm:35とhh:mm + 1:05の間の合計が表示されます。
私のプロジェクトでHammeriteの解決策を試しましたが、シリーズから欠落しているサンプルがある場合はうまくいきませんでした。以下は、metric_tableからタイムスタンプ(ts)、ユーザー名、平均測定値を選択し、27分間隔で結果をグループ化することになっているクエリの例です。
select
min(ts),
user_name,
sum(measure) / 27
from metric_table
where
ts between date_sub('2015-03-17 00:00:00', INTERVAL 2160 MINUTE) and '2015-03-17 00:00:00'
group by unix_timestamp(ts) div 1620, user_name
order by ts, user_name
;
注:27分(選択時)= 1620秒(グループ化時)、2160分= 3日(これは時間範囲です)
サンプルが不規則に記録された時系列に対してこのクエリを実行した場合(つまり、特定のタイムスタンプについて、すべてのユーザー名のメジャー値を見つける保証はありませんでした)結果は間隔に従ってスタンプされませんでした(配置されませんでした) 27分ごと)。一部のグループで予期されたfloor(ts0 + i * interval)より大きいタイムスタンプを返すmin(ts)が原因だったと思います。以前のクエリを次のクエリに変更しました。
select
from_unixtime(unix_timestamp(ts) - unix_timestamp(ts) mod 1620) as ts1,
user_name,
sum(measure) / 27
from metric_table
where
ts between date_sub('2015-03-17 00:00:00', INTERVAL 2160 MINUTE) and '2015-03-17 00:00:00'
group by ts1, user_name
order by ts1, user_name
;
また、サンプルが欠落している場合でも問題なく機能します。これは、時間の計算を選択に移すと、ts1がタイムステップと一致することが保証されるためだと思います。
別のソリューション。
任意の間隔で平均化するには、dtをタイムスタンプに変換し、間隔(例では7秒)でモジュロでグループ化します。
select FROM_UNIXTIME(
UNIX_TIMESTAMP(dt_record) - UNIX_TIMESTAMP(dt_record) mod 7
) as dt, avg(1das4hrz) from `meteor-m2_msgi`
where dt_record>='2016-11-13 05:00:00'
and dt_record < '2016-11-13 05:02:00'
group by FROM_UNIXTIME(
UNIX_TIMESTAMP(dt_record) - UNIX_TIMESTAMP(dt_record) mod 7);
それがどのように機能するかを示すために、計算を示しながらリクエストを準備します。
select dt_record, minute(dt_record) as mm, SECOND(dt_record) as ss,
UNIX_TIMESTAMP(dt_record) as uxt, UNIX_TIMESTAMP(dt_record) mod 7 as ux7,
FROM_UNIXTIME(
UNIX_TIMESTAMP(dt_record) - UNIX_TIMESTAMP(dt_record) mod 7) as dtsub,
column from `yourtable` where dt_record>='2016-11-13 05:00:00'
and dt_record < '2016-11-13 05:02:00';
+---------------------+--------------------+
| dt | avg(column) |
+---------------------+--------------------+
| 2016-11-13 04:59:43 | 25434.85714285714 |
| 2016-11-13 05:00:42 | 5700.728813559322 |
| 2016-11-13 05:01:41 | 950.1016949152543 |
| 2016-11-13 05:02:40 | 4671.220338983051 |
| 2016-11-13 05:03:39 | 25468.728813559323 |
| 2016-11-13 05:04:38 | 43883.52542372881 |
| 2016-11-13 05:05:37 | 24589.338983050846 |
+---------------------+--------------------+
+---------------------+-----+-----+------------+------+---------------------+----------+
| dt_record | mm | ss | uxt | ux7 | dtsub | column |
+---------------------+------+-----+------------+------+---------------------+----------+
| 2016-11-13 05:00:00 | 0 | 0 | 1479002400 | 1 | 2016-11-13 04:59:59 | 36137 |
| 2016-11-13 05:00:01 | 0 | 1 | 1479002401 | 2 | 2016-11-13 04:59:59 | 36137 |
| 2016-11-13 05:00:02 | 0 | 2 | 1479002402 | 3 | 2016-11-13 04:59:59 | 36137 |
| 2016-11-13 05:00:03 | 0 | 3 | 1479002403 | 4 | 2016-11-13 04:59:59 | 34911 |
| 2016-11-13 05:00:04 | 0 | 4 | 1479002404 | 5 | 2016-11-13 04:59:59 | 34911 |
| 2016-11-13 05:00:05 | 0 | 5 | 1479002405 | 6 | 2016-11-13 04:59:59 | 34911 |
| 2016-11-13 05:00:06 | 0 | 6 | 1479002406 | 0 | 2016-11-13 05:00:06 | 33726 |
| 2016-11-13 05:00:07 | 0 | 7 | 1479002407 | 1 | 2016-11-13 05:00:06 | 32581 |
| 2016-11-13 05:00:08 | 0 | 8 | 1479002408 | 2 | 2016-11-13 05:00:06 | 32581 |
| 2016-11-13 05:00:09 | 0 | 9 | 1479002409 | 3 | 2016-11-13 05:00:06 | 31475 |
+---------------------+-----+-----+------------+------+---------------------+----------+
誰かが何か速いものを提案できますか?
非常に奇妙ですが、ここでソリューションを使用しています:
私たちは次のようなものを提案できます:
select convert(
(min(dt_record) div 50)*50 - 20*((convert(min(dt_record),
datetime) div 50) mod 2), datetime) as dt,
avg(1das4hrz)
from `meteor-m2_msgi`
where dt_record>='2016-11-13 05:00:00'
and dt_record < '2016-11-14 00:00:00'
group by convert(dt_record, datetime) div 50;
select (
convert(
min(dt_record), datetime) div 50)*50 - 20*(
(convert(min(dt_record), datetime) div 50) mod 2
) as dt,
avg(column) from `your_table`
where dt_record>='2016-11-13 05:00:00'
and dt_record < '2016-11-14 00:00:00'
group by convert(dt_record, datetime) div 50;
50は、[〜#〜]通常[〜#〜]の1/2が30秒であるのに対し、「整数日付フォーマット」は、 50