質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

2回答

920閲覧

mysql 平均計算 指定フィールド

syu-yu

総合スコア24

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

0クリップ

投稿2017/11/13 08:47

やりたいこと
⓵為替APIを10秒間に1回取得し、mysqlに格納。
⓶その後格納された直近3つの値(計30秒)の平均を⓷mysqlに格納したい。

不明点
⓶における文の書き方。どのようにすれば平均値を獲得できるのか。
⓵,⓷はgcpとinsert intoにて確認済み。

イメージ
table
time | usd_rate |
1 | 111 |
2 | 112 |
3 | 113 | →(111+112+113)/3(ここをやりたい。)
4 | 114 | →(112+113+114)/3
・・
・・・
ウィンド関数をやはり使うべきなのでしょうか??
お手数おかけしますが、ご教示お願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2017/11/13 09:01

timeは連続しているという保証がありますか?また1,2は自分を含む前のデータ数が3に満たないためnullということでよいですか?
syu-yu

2017/11/13 09:10

基本的には連続している前提です。また、1.2はデータ数が3に満たないためnull扱いで、大丈夫です!
guest

回答2

0

条件次第ですが

  • 元データ

SQL

1create table tbl(time int unique,usd_rate double); 2insert into tbl values(1,111),(2,112),(3,113),(4,114);
  • 集計

SQL

1select t1.time,(t1.usd_rate+t2.usd_rate+t3.usd_rate)/3 as avg_usd_rate from tbl as t1 2left join tbl as t2 on t1.time=t2.time+1 3left join tbl as t3 on t1.time=t3.time+2
  • 追記

よくよく考えるとこうすると効率的かもしれません

SQL

1select t1.time, 2(select avg(usd_rate) from tbl as t2 3where t2.time between t1.time -2 and t1.time 4having count(*)>2) as usd_avg 5from tbl as t1;

※それもこれもtimeが連続している前提です

投稿2017/11/13 09:18

編集2017/11/14 04:25
yambejp

総合スコア114810

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syu-yu

2017/11/16 06:19

ありがとうございます。 色々な方法があるのですね! 試してみます!
guest

0

ベストアンサー

こちらですが、下記のやり方であればテーブル結合不要になるのではないかと思います。

sql

1SELECT 2 CASE WHEN COUNT(*) < 3 THEN NULL ELSE AVG(usd_rate) END AS avv_usd_rage 3FROM 4 (SELECT * FROM `table` order by time desc limit 3) AS latest_table

※「直近3回分」のレコードを取得→3件あれば平均値を取得、2件未満ならNullを返します。

なお、2件未満の場合は「その時に存在する分の平均値」を取得するのであればCASE文は不要で

sql

1SELECT 2 AVG(usd_rate) AS avv_usd_rage 3FROM 4 (SELECT * FROM `table` order by time desc limit 3) AS latest_table

だけになります。

この結果を他のテーブル(table2)に入れる場合、手前にINSERT文を付ければOKです。

sql

1create table avg_table(time int unique,usd_rate double);

sql

1INSERT INTO avg_table 2SELECT 3 MAX(time) AS time, 4 CASE WHEN COUNT(*) < 3 THEN NULL ELSE AVG(usd_rate) END AS avg_usd_rage 5FROM 6 (SELECT * FROM `table` order by time desc limit 3) AS latest_table

※同じ時間帯に対して複数回実行する可能性がある場合は、
後から来たデータを優先する場合: INSERT INTO → REPLACE INTO
先に格納されていたデータを優先する場合: INSERT INTO → INSERT IGNORE INTO
に変更してください。

投稿2017/11/14 05:11

nak

総合スコア696

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問