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

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

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

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

Q&A

解決済

2回答

1446閲覧

デイリーレポートのようなテーブルから差分を条件にしてデータを取り出したい

y_y3

総合スコア179

MySQL

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

0グッド

0クリップ

投稿2017/06/09 12:35

編集2017/06/10 01:15

mysqlで以下のようなデイリーレポートテーブルを作成しました。
1日1レコードずつstockに紐づくstock_reportが作成されていきます。その時に作成された日付がreported_atには入ります。

mysql

1stock 2 `id` int(11) 3 `name` varchar(255) 4 5stock_report 6 `id` int(11) 7 `stock_id`, int(11) 8 `reported_at` date 9 `value` int(11)

質問1. 指定した二つのreported_atのvalueの差分が◯以上のstockを抽出したいのですがsqlだけで完結させることは可能でしょうか。

例: reported_atが6月5日のvalueと6月6日のvalueの差分の絶対値が50以上のstockを抽出する。

質問2. この様な抽出を行いたい時に作成するデイリーレポートテーブルは上記の様なテーブル構成で間違っていないでしょうか。デイリーで増えていくようなテーブル構成が知りたいです。

要件だけですがよろしくお願いします。

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

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

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

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

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

SVC34

2017/06/09 22:13 編集

質問の上では要件を正確に記載してください。区間というのはreported_atの日付による期間を意味しているのでしょうか。差分というのはその期間の終わりのvalue-初めのvalueで計算するのでしょうか。レコードは毎日必ず作成されますか。日差分が○以上は絶対値で見るのでしょうか。
guest

回答2

0

To: hihijijiさん
下から3行目の r1. がダブってますね。

hihijijiさんのSQLだとどのくらいの速度かなー、と思って、実際にデータを作ってやってみました。
id に primary制約くらいしかつけてない、いい加減な感じでテーブルを作りました。
環境はBash on ubuntu on Windows上のmysql 5.7です。

stockが2,000レコード、2016年の日付で366日なので、stock_reportは732,000レコード。
valueは0~99のランダムです。

SQL

1SELECT DISTINCT stock.name,r1.`value`,r1.reported_at,r2.`value`,r2.reported_at 2FROM stock_report AS r1 3 INNER JOIN stock_report AS r2 ON r1.stock_id = r2.stock_id 4 INNER JOIN stock ON stock.id = r1.stock_id 5WHERE 6 r1.reported_at = '2016-06-05' AND 7 r2.reported_at = '2016-06-06' AND 8 ABS(r1.value - r2.value) >= 50;

結果は

518 rows in set (0.77 sec) ```なかなか高速ですね。 サブクエリで絞ってからの方が速いのかな?と思って ```SQL SELECT DISTINCT stock.name,r1.`value`,r1.reported_at,r2.`value`,r2.reported_at FROM (SELECT * FROM stock_report WHERE reported_at = '2016-06-05') AS r1 INNER JOIN (SELECT * FROM stock_report WHERE reported_at = '2016-06-06') AS r2 ON r1.stock_id = r2.stock_id INNER JOIN stock ON stock.id = r1.stock_id WHERE ABS(r1.value - r2.value) >= 50; ```としたら、結果は

518 rows in set (1.03 sec)

投稿2017/06/10 10:46

shi_ue

総合スコア4437

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

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

0

ベストアンサー

クエリはこうかな?

SQL

1SELECT DISTINCT stock.name 2FROM stock_report AS r1 3 INNER JOIN stock_report AS r2 4 ON r1.stock_id = r2.stock_id 5 INNER JOIN stock 6 ON stock.id = r1.r1.stock_id 7WHERE r1.reported_at = '2017-06-05' AND r2.reported_at = '2017-06-06' 8 AND ABS(r1.value - r2.value) >= 50

stock_report の数が数桁程度ならこれでいいと思います。
それ以上ならキーや制約、インデックスによります。
大きく超えるなら工夫が必要です。

投稿2017/06/10 01:42

hihijiji

総合スコア4150

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問