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

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

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

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

Q&A

解決済

5回答

8167閲覧

[MySQL]移動平均を求めたい

退会済みユーザー

退会済みユーザー

総合スコア0

MySQL

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

1グッド

4クリップ

投稿2015/06/07 16:39

日付と銘柄コードと株価が格納されているテーブルから移動平均値を求めたいのですがSQLが思い浮かびません。

テーブルは以下になります。
kabuka

| date | code |close|

| 2015-06-07 | 7974 |1000 |

| 2015-06-07 | 7974 |2000 |

私が考えたSQLはめちゃくちゃ重くて使い物になりませんでした

lang

1 select date,close, 2 (select 3 avg(b.close) 4 from kabuka b 5 where ( 6 select count(*) 7 from kabuka c 8 where c.date between b.date and a.date and c.code = a.code 9 ) between 1 and 25 AND b.code = a.code 10 having count(*) = 25) as avg25,

宜しくお願いします。

退会済みユーザー👍を押しています

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

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

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

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

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

guest

回答5

0

kantomiさんのユーザ変数を使った方法ですが、

OracleACEのAketiJyuuzouさんとyoku0825さんと
日本オラクルの木村さんによると
MySQLのユーザ変数は評価順序が未定義だそうです。
http://qiita.com/AketiJyuuzou/items/cced9b70cc714b382d98

ゆえに、結果が保証されないと思います。

投稿2016/04/01 09:03

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

返信遅れてしまい申し訳ありません
結局日付を先に求めてからupdateしました

投稿2015/07/01 10:58

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

ベストアンサー

SQLはシーケンシャルな処理を苦手としますので、あまりSQL向きの処理じゃないですね。
(仮に、1000日分のデータがあれば、1000倍のイメージを作ってから処理することになっているはず)

25営業日の移動平均を取りたいのであれば、まずはシーケンスを振ったワークテーブルを作るのが良いかもしれません。

lang

1SET @i := 0; 2SET @code := 0; 3 4CREATE TABLE work AS 5SELECT 6 * 7 , @i := CASE WHEN @code = code THEN @i + 1 ELSE 1 END AS i -- コードごとのシーケンス 8 , @code := code AS ref 9FROM kabuka 10ORDER BY code, date; 11 12ALTER TABLE work ADD KEY(code, date DESC); -- MySQLはDESCは効かなかったような気もする。

上で使ったシーケンスの振り方はMySQL特有です。
他のDBであれば

lang

1ROW_NUMBER()OVER(PARTITION BY code ORDER BY date) AS i

いずれにしても、サブクエリのままでやるとインデックスが使えないので、データ量によってはワークを作った方が速いでしょう。

ワークテーブルを繋いで計算するのは以下の通り。

lang

1SELECT m.code, m.date , AVG(close) 2FROM 3 work m 4 INNER JOIN work s 5 ON m.code = s.code 6 AND m.date >= s.date 7 AND m.i < s.i + 25 8GROUP BY m.code, m.date 9HAVING COUNT(*) = 25

未テストです。

投稿2015/06/08 08:12

編集2015/06/08 08:13
kantomi

総合スコア295

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

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

退会済みユーザー

退会済みユーザー

2018/09/17 22:22

幸運にも期待通りの結果を得られるかもしれませんが、それが確約されないSQLで、 業務では問題外の品質なので、マイナス投票します。 http://download.nust.na/pub6/mysql/doc/refman/5.1/ja/user-variables.html >基本的なルールは、ステートメントの一部でユーザ変数値を割り当てないこと >および同一ステートメント内の他部分で同じ変数を使用しないことです。 >期待通りの結果を得られるかもしれませんが、これは確約されていません。
aiou

2019/04/06 13:43

退会済ユーザ様 減点するなら下記の3点がより適切です。 https://dev.mysql.com/doc/refman/5.6/ja/user-variables.html >SET ステートメント以外では、同じステートメント内で、 >ユーザー変数に値を割り当ててその値を読み取ることは決してしないでください。 という記載に反して、割り当てた値を、読み取っていることが1点目。 select文でのユーザ変数への値の代入は5.7で非推奨になり、8.0以降で削除予定の機能であることが2点目。 http://www.mysql.gr.jp/mysqlml/mysql/msg/16488 MySQLの開発者がブログに https://mysqlserverteam.com/row-numbering-ranking-how-to-use-less-user-variables-in-mysql-queries/ It works. But it relies on the fact that MySQL sets @rownum before setting @prev_sex, i.e. evaluates selected expressions from left to right. Which is true for this query, but not for all queries と書いてあるのが3点目。
guest

0

SQLが途中で途切れているようですが、特に未記載部分に条件がないと仮定するとdatecodeにインデックスはられていれば、そこまで重くないように思います。
そもそもどの程度の性能を求めるのでしょうか。

投稿2015/06/08 00:56

sho_cs

総合スコア3541

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

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

0

SQLめちゃくちゃに見えますが、これエラーになりませんか?

投稿2015/06/08 00:37

orange0190

総合スコア1698

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問