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

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

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

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

Q&A

解決済

2回答

2626閲覧

MySQLでユーザーの最初のアクションから30日経過までのデータを合計したい。

chikaraishikura

総合スコア7

MySQL

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

0グッド

0クリップ

投稿2015/09/02 08:14

MySQL初心者です。説明不足になるかもしれませんが、その際はご指摘いただけますと助かります。

■データテーブル
テーブルにあるカラムは以下です。
user_name
ユーザーのIDです。ユニークです。
purchase
購入金額です。
purchased_at
購入した時の時間です。2015-01-01 11:11:11という形です。

■質問内容
ユーザーごとに最初に購入した時間から30日間の合計購入金額を出したいと考えております。

以下のような構文で合計金額を出そうとしたのですがうまくいきません。

SELECT user_name,
SUM(purchase)
FROM テーブル名
WHERE purchased_at >= ANY (SELECT MIN(purchased_at) FROM テーブル名 GROUP BY user_name)
AND
purchased_at <= ANY (SELECT MIN(purchased_at) + INTERVAL 30 DAY FROM テーブル名 GROUP BY user_name)
GROUP BY user_name
;

現在までの合計がなぜか出てしまいます。
お手数をおかけいたしますが
ご教授いただければと思います。

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんな感じでいかがでしょう

TBLはテーブル名にしてください

SQL

1SELECT 2 TBL.user_name 3 , SUM(TBL.purchase) 4FROM TBL 5JOIN ( 6 SELECT 7 user_name 8 , MIN(purchased_at) purchased_at 9 FROM TBL 10 GROUP BY 11 user_name 12) FIRST 13ON TBL.user_name = FIRST.user_name 14AND TBL.purchased_at <= DATE_ADD(FIRST.purchased_at, INTERVAL 30 DAY) 15GROUP BY 16 user_name 17

投稿2015/09/02 09:11

編集2015/09/02 09:14
kutsulog

総合スコア985

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

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

chikaraishikura

2015/09/02 09:27

kutsulogさん ありがとうございます!無事に算出できました。 応用が利くようにこちらを参考に勉強してまいります。 本当に助かりました。
guest

0

動作検証してないので怪しいですが、こんな感じで出ませんでしょうか?
ID,最小日のリストを作って、そこにID毎のデータを連結、最小日との差が30日を超えるのものを除外

SQL

1SELECT b.user_name, SUM(d.purchase) 2FROM ( 3 SELECT user_name, MIN(purchased_at) AS min_at 4 FROM テーブル名 5 GROUP BY user_name ) b 6LEFT JOIN テーブル名 d ON d.user_name = b.user_name 7WHERE d.purchased_at < = (b.min_at + INTERVAL 30 DAY) 8GROUP BY b.user_name

提示されているSQLはIDの縛りが無いので、USER1のある購入日がUSER5の最小日の30日以内だったとしてもHITしてしまう場合があると思います。

投稿2015/09/02 09:14

hirohiro

総合スコア2068

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

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

chikaraishikura

2015/09/03 02:33

hirohiroさん、ありがとうございます! こちらでも無事に出せました。 kutsulogさんのSQLで算出した値と比較してみましたが 同じ物が出されているようなので、問題はないようです。 結合についてはまだ何もわかっておりませんので お二人のやり方を見比べながら勉強してまいりたいと思います。 ありがとうございます。助かりました。
hirohiro

2015/09/06 04:18 編集

エイリアス名など細かい違いはありますがほぼ同じSQLです。 投稿前に一度更新して確認したんですが、表現の修正をしている間(投稿時間差3分)に投稿があったようで内容が重複しているものを上げてしまいました。 因みに「join」とだけ書くと「inner join」として働くようです。 「left join」は右辺の結合テーブルでnullの行も抽出しますが「inner join」は結合の左右どちらかで1行も存在しない行を省きます。 これらと「Right join」は、例えば「商品テーブル」と「売り上げテーブル」を商品名で結合したときに、商品テーブルに存在しない商品の売り上げや、売り上げレコードゼロの商品を省くか否かといった場合に使い分けます。 今回は同じテーブル同士を結合しており、片方に存在する「user_name」がもう片方には1行もないということはありませんので、結果は同じになります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問