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

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

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

COUNT は、広く使用されているSQLの関数です。COUNT関数は、行数、もしくは配列のエンティティの数をカウントします。

MySQL

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

Q&A

解決済

1回答

1600閲覧

複数の条件を組み合わせて抽出したい。

yunak

総合スコア2

COUNT

COUNT は、広く使用されているSQLの関数です。COUNT関数は、行数、もしくは配列のエンティティの数をカウントします。

MySQL

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

0グッド

0クリップ

投稿2020/06/16 12:08

編集2020/06/16 16:38

mysql

1create table mydb.login_log (user_id integer, timestamp timestamp); 2create table mydb.charge_log (user_id integer, timestamp timestamp, category char(10)); 3create table mydb.quest_log (user_id integer, timestamp timestamp, quest_id integer); 4 5LOAD DATA LOCAL INFILE 'C:/Windows/Temp/login_log.csv' INTO TABLE mydb.login_log 6 FIELDS 7 TERMINATED BY ',' 8 ENCLOSED BY '"' 9 LINES TERMINATED BY '\r\n'; 10 11LOAD DATA LOCAL INFILE 'C:/Windows/Temp/charge_log.csv' INTO TABLE mydb.charge_log 12 FIELDS 13 TERMINATED BY ',' 14 ENCLOSED BY '"' 15 LINES TERMINATED BY '\r\n'; 16 17LOAD DATA LOCAL INFILE 'C:/Windows/Temp/quest_log.csv' INTO TABLE mydb.quest_log 18 FIELDS 19 TERMINATED BY ',' 20 ENCLOSED BY '"' 21 LINES TERMINATED BY '\r\n'; 22 23```### 前提・実現したいこと 24sqlで、複数の条件に合致したデータを抽出したい。 25 26具体的には、 27ログインの履歴を持つデータ(login_log)と 28課金の履歴を持つデータ(charge_log)と 29クエストの履歴を持つデータ(quest_log)を用いて 301月に課金(charge_logのcategoryがbuy)したユーザーについて、 31ユーザーごとに、 32ユーザーID・2月のログイン回数・2月にクエストを行った日数・2月にクエストを行った回数を出力したい。 33 34(ex) 35login_log 36user_id | timestamp 37001 |2020-01-01 12:10:00 38001 |2020-01-18 19:15:00 39002 |2020-01-17 09:40:00 40... 41 42charge_log 43user_id | timestamp |category 44001 |2020-01-01 12:10:00 |buy 45002 |2020-01-17 09:40:00 |present 46... 47 48quest_log 49user_id | timestamp |quest_id 50001 |2020-01-01 12:15:00 |10001 51002 |2020-01-17 09:47:00 |10002 52... 53 54 55### 発生している問題 56出力したログイン回数、クエストを行った日数、クエストを行った回数の数値が誤っている。 57 58### 該当のソースコード 59SELECT 60 t1.user_id AS 'ユーザーID' 61 ,COUNT(t2.user_id) AS '2月のログイン回数' 62 ,COUNT(DATE(t3.timestamp)) AS '2月でクエストを行った日数' 63 ,COUNT(t3.quest_id) AS '2月でクエストを行った回数' 64FROM charge_log t1 65 LEFT JOIN login_log t2 66 ON 67 t1.user_id = t2.user_id 68 AND 69 MONTH(t2.timestamp) = 2 70 LEFT JOIN quest_log t3 71 ON 72 t1.user_id = t3.user_id 73 AND 74 MONTH(t3.timestamp) = 2 75WHERE 76 t1.category = 'buy' 77AND 78 MONTH(t1.timestamp) = 1 79GROUP BY 80 t1.user_id 81; 82 83### 試したこと 84一旦ログイン回数だけを出力するsqlを考えて実行したところ、正しい数値を出力することができたが 85全体のsqlに組み込む方法がわからない。 86 87実行したsql: 88select 89t1.user_id 90,count(t1.user_id) as '2月のログイン回数' 91from login_log t1 92left join charge_log t2 93on t1.user_id = t2.user_id 94where month(t1.timestamp) = 2 95and 96 t2.category = 'buy' 97and 98 month(t2.timestamp) = 1 99group by 100 t1.user_id 101;

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

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

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

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

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

yunak

2020/06/16 12:46 編集

お教えいただきありがとうございます。 今回使用しているデータが外部から提供されたデータであり、公開するのに抵抗があるため、類似のデータとして例を記載しております。 それだと回答しにくいかとは思うのですが、記載できず申し訳ございません。
Orlofsky

2020/06/16 12:36

質問を修正してください。 SELECT文が書いてあるからデータはテーブルに入っているのはわかっているから、CSVの話は全部削りましょう。 charge_log, login_log , quest_log のテーブルの説明をCREATE TABLE文とINSERT文に直してください。
sazi

2020/06/16 12:56

ログイン, 課金, クエストはそれぞれで独立(ログインだけとか課金だけとかがある)していますか?
yunak

2020/06/16 12:58

修正しました。 修正対応をすることが初めてなので、対応方法等誤っていたらお教えいただけると幸いです。 お手数をお掛けしますが、何卒宜しくお願いいたします。
yunak

2020/06/16 13:06

完全に独立はしていないです。 ログインをした後に、複数回課金やクエストが行われることはありますが、 ログインを一度もせずに課金やクエストが行われることはありません。 課金とクエストの間には関係性はありません。
Orlofsky

2020/06/16 13:16

sazi さんにお任せします。疲れました。
guest

回答1

0

ベストアンサー

1月に課金(charge_logのcategoryがbuy)したユーザーについて、
ユーザーごとに、ユーザーID・2月のログイン回数・2月にクエストを行った日数・2月にクエストを行った回数を出力したい。

複数のテーブルで集計する際には、集計する単位で揃える必要があります。

SQL

1select login.user_id 2 , login.cnt as login_count 3 , coalesce(quest.day_count, 0) as quest_day_count 4 , coalesce(quest.cnt, 0) as quest_count 5from ( 6 select user_id, count(*) as cnt 7 from login_log 8 where MONTH(timestamp) = 2 9 and user_id in ( 10 select user_id 11 from charge_log 12 where MONTH(timestamp) = 1 and category = 'buy' 13 ) 14 group by user_id 15 ) login 16 left join ( 17 select user_id, count(*) as cnt, count(distinct date(timestamp)) as day_count 18 from quest_log 19 where MONTH(timestamp) = 2 20 group by user_id 21 ) quest 22 on login.user_id=quest.user_id

投稿2020/06/16 13:18

編集2020/06/16 16:44
sazi

総合スコア25195

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

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

yunak

2020/06/16 14:18

ご回答いただきありがとうございます。 理解能力が足りず大変申し訳ないのですが、「集計する単位で揃える」というのは ご記載いただいたSQLで言うとどの部分にあたりますか? coalesceを調べてみたところ「リストの最初の非NULL値を返す」ということだったので これはまた別の目的で使用している句だと認識しております。 また、記載していただいたSQLを実行したところ、 5月にログインしていないユーザーのレコードも出力されました。 where MONTH(timestamp) = 5 の部分で条件が絞られるはずだと思っており、原因が思い当たりません。 何度も質問してしまい大変申し訳ございません。 ご教授いただけると幸いです。
sazi

2020/06/16 14:28

この場合の揃えるというのはuser_idです。 user_id毎に集計するのですから、集計してから結合します。 結合してdistinctでも場合によっては大丈夫でしょうけど。
sazi

2020/06/16 14:35 編集

>5月にログインしていないユーザーのレコードも出力されました。 質問でOKだったと言われる内容とその部分のSQLは変わりませんけど? 条件はあくまで質問のものを使用していますので、分かりませんが、月だけではなく、年も必要だったりしませんか?
sazi

2020/06/16 14:32

coalesce()は、ログインしているけど、クエストしていないような場合にはNullになるので0に置き換える考慮です。
sazi

2020/06/16 16:45 編集

条件を合わせました。 ※年月じゃなくていいのかは気になりますが。
yunak

2020/06/17 11:14

「集計する単位で揃える」について、user_id毎という意味であるという旨、理解しました。 ありがとうございます。 質問に記載したSQLにミスがあったので編集しました。 失礼いたしました。 coalesce()の用途についても理解できました。 ありがとうございます。 今存在しているデータは年を跨ぐものがないので月だけを指定しておりましたが、 今後運用していくことを考えると年も必要になります。 ご指摘いただき、ありがとうございます。 教えていただいた内容を踏まえて、書き直してみます。 本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問