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

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

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

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

4回答

1680閲覧

MySQL5.6で最新の3日間、7日間、30日間の平均値を出力したいです

knrdai

総合スコア11

MySQL

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2017/08/27 06:48

編集2017/08/27 11:46

###MySQL5.6で最新の3日間、7日間、30日間の店舗ごとの売上平均値を出力したいです
MySQL5.6で最新の3日間、7日間、30日間の店舗ごとの売上平均値を出力したいです。データは1日ごとに、ひとつのテーブルに入っています。

'SELECT AVG(A店売上), AVG(B店売上), AVG(C店売上), AVG(D店売上) FROM 売上一覧'

この続きをどう書けばよろしいのでしょうか。
SQL文が分かる方、ご教授くださいませ。よろしくお願いします。

追記
後出しで申し訳ありません、出力はPHPです。
PDOのコードはデータベースに接続したあと、

php

1$stmt = $db->prepare('SELECT AVG(A店売上), AVG(B店売上), AVG(C店売上), AVG(C店売上), AVG(D店売上), AVG(E店売上), AVG(F店売上) FROM 売上一覧'); 2$stmt->execute(); 3$Result_ave = $stmt->fetch(PDO::FETCH_ASSOC);

foreachで$Result_aveを出力しています。
このコードでは全件の平均値になってしましまいます。

オートインクリメントでIDがあるので、日付等を指定しなくても、常に最新のIDの3,7,30件の平均値をAVGで求める事は可能でしょうか

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/08/27 06:55

CREATE 文で表現されるテーブル定義と、サンプルデータを提示してください。
knrdai

2017/08/27 11:48

追記を記入しました。後出しで申し訳ありません
退会済みユーザー

退会済みユーザー

2017/08/27 14:04

テーブルの定義を追記してください。
knrdai

2017/08/27 14:22

何度もお手数をお掛けし、すいません。テーブルの定義とはテーブルの構造のことでしょうか? テーブルの構造は、 ID(INT),A店売上(INT),B店売上(INT),C店売上(INT),D店売上(INT),E店売上(INT),F店売上(INT),更新日(TIMESTAMP) になっております。
SVC34

2017/08/27 22:50

3日間、7日間、30日間それぞれの平均を一回のSQLで求めたいのでしょうか
knrdai

2017/08/28 14:10

3、7、30日間別の関数にしようと思っているので、一つづつで構いません
guest

回答4

0

まず、A店売上, B店売上・・・がカラムが別れているのはSQL的な
データ管理ではありません。
日付,お店,売上で管理するのが普通でしょう。

現行の管理を採用するとして、
idごとに必ず各お店の売上が絶対にうまっているのかによって
過去ナン日というロジックがかわってきます。
またid順で管理するとして連続しているのか抜け番があるかによっても違います
idの浅いデータは履歴がすくないため平均が正確にとれないのは問題ないですか?
(たとえば最初の10個目のデータは30日の平均は取れない)

投稿2017/08/28 00:29

yambejp

総合スコア114775

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

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

knrdai

2017/08/28 14:30

ご返答ありがとうございます。 データに抜けている部分や、idに抜け番はありません。また、履歴の少ないときの正確性も考慮していただかなくて、大丈夫です
knrdai

2017/08/29 14:35

データベースの設計からきちんと勉強したいと思います。ありがとうございました。
guest

0

SVC34様のご指摘の通り間違っておりましたので修正いたしました。ご指摘大変ありがとうございます。
1レコードに全店1日分の入っているレコードだとして、平均を3ラインで出力

sql

1(SELECT ' 3日売上平均' 日数, AVG(`A店売上`) A店, AVG(`B店売上`) B店, AVG(`C店売上`) C店, AVG(`D店売上`) D店, AVG(`E店売上`) E店, AVG(`F店売上`) F店 2 FROM (SELECT * FROM `売上一覧` ORDER BY id DESC LIMIT 3) TB) 3UNION ALL 4(SELECT ' 7日売上平均' 日数, AVG(`A店売上`), AVG(`B店売上`), AVG(`C店売上`), AVG(`D店売上`), AVG(`E店売上`), AVG(`F店売上`) 5 FROM (SELECT * FROM `売上一覧` ORDER BY id DESC LIMIT 7) TB) 6UNION ALL 7(SELECT '30日売上平均' 日数, AVG(`A店売上`), AVG(`B店売上`), AVG(`C店売上`), AVG(`D店売上`), AVG(`E店売上`), AVG(`F店売上`) 8 FROM (SELECT * FROM `売上一覧` ORDER BY id DESC LIMIT 30) TB) 9ORDER BY 1;

.
.
.

売上一覧のテーブルを仮想定して作成してみました。 最新3日のみですが、後はintervalを変更するのはどうでしょうか。

sql

1create table `売上一覧` (`店コード` char, `売上日` date, `売上` int); 2 3SELECT AVG(`A店売上`), AVG(`B店売上`), AVG(`C店売上`), AVG(`D店売上`) FROM 4 ( 5 SELECT CASE WHEN `店コード`='A' THEN `売上` ELSE NULL END `A店売上`, 6 CASE WHEN `店コード`='B' THEN `売上` ELSE NULL END `B店売上`, 7 CASE WHEN `店コード`='C' THEN `売上` ELSE NULL END `C店売上`, 8 CASE WHEN `店コード`='D' THEN `売上` ELSE NULL END `D店売上` 9 FROM `売上一覧` WHERE 10 `売上日` BETWEEN SUBDATE((SELECT MAX(`売上日`) FROM `売上一覧`),3 - 1) AND (SELECT MAX(`売上日`) FROM `売上一覧`) 11 ) t1 12; 13

投稿2017/08/27 07:55

編集2017/08/29 19:16
A.Ichi

総合スコア4070

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

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

A.Ichi

2017/08/27 09:03

上記の方法の場合、売り上げが無い店舗(店休?)の平均の分母が他と異なります。
knrdai

2017/08/27 11:50

追記を記入しました。後出しで申し訳ありませんが、常に最新のIDから3,7,30件の平均値をAVGで求める事は可能でしょうか
A.Ichi

2017/08/28 00:44

確認ですが、レコードは各店の1日の売上が作成されていて、そのIDが連番で古い順から振られているテーブルが有ると言うことでしょうか?
knrdai

2017/08/28 14:23

ひとつのレコードに全店舗1日分のデータが入ってます
A.Ichi

2017/08/28 15:35

ひとつのレコードに入っていたのですね。勘違いをしておりました。3行で出力する様にしました。
knrdai

2017/08/29 14:36

拙い説明で申し訳ありませんでした。SQLもPHPももっと勉強します
guest

0

日付で絞る場合はこんな感じです。

SQL

1'SELECT AVG(A店売上), AVG(B店売上), AVG(C店売上), AVG(D店売上) FROM 売上一覧 WHERE 日付 > 20170826 AND 日付 < 20170827'

テーブル定義とサンプルレコードを記載いただければもう少し詳細な回答が出来るかと思います。

投稿2017/08/27 07:17

編集2017/08/27 07:19
wuzzy

総合スコア152

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

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

knrdai

2017/08/27 11:51

ご返答ありがとうございます。 追記を記入しました。後出しで申し訳ありませんが、常に最新のIDから3,7,30件の平均値をAVGで求める事は可能でしょうか
wuzzy

2017/08/27 15:00 編集

``` 'SELECT AVG(A店売上), AVG(B店売上), AVG(C店売上), AVG(D店売上) FROM 売上一覧 ORDER BY ID DESC LIMIT 3' ``` 日付を取り払っていますが、このような感じでしょうか。
knrdai

2017/08/27 15:13

ご返答ありがとうございます。 ORDER BY ID DESC LIMIT 3 が有効になっていないようで、全件の平均値になってしまいます。 PDOを使うと金額が文字列として返ってきてしまうので、SQLでなんとかしようとしていますが、普通はPHP側で計算するものでしょうか?
guest

0

ベストアンサー

これまで出てきた要件からすると、こうでしょうか

sql

1SELECT 2 AVG(`A店売上`) 3 ,AVG(`B店売上`) 4 ,AVG(`C店売上`) 5 ,AVG(`D店売上`) 6FROM ( 7 SELECT 8 `A店売上` 9 ,`B店売上` 10 ,`C店売上` 11 ,`D店売上` 12 FROM 13 `売上一覧` 14 ORDER BY 15 ID DESC 16 LIMIT 3 17) AS tmp

投稿2017/08/28 14:39

SVC34

総合スコア1149

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

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

knrdai

2017/08/29 14:34

やりたいことズバリのSQL文でした。ベストアンサーにさせていただきます。ありがとうございました。副問合せをもっと勉強したいと思います
SVC34

2017/08/29 14:44 編集

他の方の回答ではAVGによる集計とLIMITを同時に使用しているのですが、LIMITにより件数が制限されるのは集約関数等SELECT句の評価を行った後であるため、結局全レコードが集計対象になってしまいます。そこで、一度副問合せで集計せずに最新のnレコードを取得し、外側のクエリで集計するようにしています。 SELECT文の評価順序の話 http://qiita.com/suzukito/items/edcd00e680186f2930a8
knrdai

2017/08/29 14:59

ありがとうございます。参考にさせていただきます。SQLはプログラミング言語に依存することなく重要なのできちんと勉強しようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問