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

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

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

MySQL Workbenchは、オープンソースのデータベースモデリングツールです。ビジュアルなデータベース設計・SQL開発・サーバー設定・ユーザー管理・バックアップといった様々な管理ツールを備えます。

MySQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Q&A

解決済

2回答

642閲覧

退会者を抽出する方法(MySQL)

saider_san

総合スコア14

MySQL Workbench

MySQL Workbenchは、オープンソースのデータベースモデリングツールです。ビジュアルなデータベース設計・SQL開発・サーバー設定・ユーザー管理・バックアップといった様々な管理ツールを備えます。

MySQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

0グッド

1クリップ

投稿2020/06/16 06:25

前提条件

メンバーテーブル member m

idmail_addresname
1test@hoge.jptestA
2test2@hoge.jptestB
3test3@hoge.jptestC

契約商品テーブル member_item mi

idmember_idstart_dateend_date
112020/01/012020/03/30
222020/01/012020/04/30
322020/05/01null
432020/05/012020/06/30
532020/07/012020/08/31

以下のクエリを実行すると、

SELECT m.id, m.name, mi.start_date, mi.end_date FROM member m INNER JOIN member_item mi ON m.id = mi.member_id

クエリ実行後

idnamestart_dateend_date
1testA2020/01/012020/03/30
2testB2020/01/012020/04/30
2testB2020/05/01null
3testC2020/05/012020/06/30
3testC2020/07/012020/08/31

上記の表で抽出されます。

今回したいこと→退会者のみ抽出したい

退会者を判断する材料としては、
定額制の商品には適用開始期間(start_date)と適用終了期間(end_date)があり、
end_dateに値が入っていると退会者とします。
表で言うとtestAは退会者に該当します。

しかし、定額制の商品は別の商品で再契約ができてしまいます。
testBのように別商品で5月(start_date)と再度契約することができます。
この場合、testBは再契約しているので、退会者には該当しません。

※中には再契約後に退会する人もいます。(該当者testC)

試したこと

SELECT m.id, m.name, mi.start_date, mi.end_date FROM member m INNER JOIN member_item mi ON m.id = mi.member_id WHERE mi.end_date IS NOT NULL //追加

ひとまずend_dateが無い場合は表に出さないようにした。
すると、以下のように抽出されます。

idnamestart_dateend_date
1testA2020/01/012020/03/30
2testB2020/01/012020/04/30
3testC2020/05/012020/06/30
3testC2020/07/012020/08/31

今回知りたいこと

・この場合における、testBを抽出条件に出さない方法
・testCは最新の退会日付が入っているレコードのみを抽出したい

何か方法面などご教示頂けますと幸いです。

出したいクエリ

idnamestart_dateend_date
1testA2020/01/012020/03/30
3testC2020/07/012020/08/31

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

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

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

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

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

saider_san

2020/06/16 07:19

Orlofsky様 コメントありがとうございます! アドバイスありがとうございます。 以後、そのように質問形式を変更して質問しようと思います。
m.ts10806

2020/06/16 11:51

退会者はどのようにデータ管理しているのでしょう。
m.ts10806

2020/06/16 11:52

あぁ、終わってた。 「以後」ではなく「今」してください。質問は編集できますし、「次」とすると大抵忘れます。
guest

回答2

0

こうして、こう!MySQL苦手。
ただ何となくtestBみたいなデータの判定がまずそうに思うなあ…。

sql

1select m.id,m.name,mi.start_date,mi.end_date 2from member m 3 inner join member_item mi on mi.member_id=m.id 4 and mi.id = ( 5 select id 6 from member_item x 7 where x.member_id=m.id 8 order by x.end_date is null desc,x.end_date desc 9 limit 1 10 ) 11where mi.end_date is not null

投稿2020/06/16 06:55

編集2020/06/16 06:57
sousuke

総合スコア3830

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

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

saider_san

2020/06/16 07:17

sousuke様 コメントありがとうございます! こちらのパターンで取りたいデータが取得ができました。 こういった書き方もあるのだなと、とても勉強になりました。 ありがとうございます!
guest

0

ベストアンサー

最新を取得すれば、end_dateの判断だけですね。

SQL

1SELECT m.id, m.name, mi.start_date, mi.end_date 2from member_item mi inner join member m 3 om mi.menber_id = m.id 4where not exists( 5 select 1 from member_item 6 where menber_id=mi.menber_id and start_date > mi.start_date 7 ) 8 and end_date is not null

どっちが低コストか分かりませんが、別パターン

SQL

1SELECT m.id, m.name, mi.start_date, mi.end_date 2from member_item mi inner join member m 3 om mi.menber_id = m.id 4where (mi.menber_id, mi.start_date) in ( 5 select menber_id, max(start_Date) 6 from member_item 7 group by menber_id 8 ) 9 and end_date is not null

投稿2020/06/16 06:37

編集2020/06/16 07:22
sazi

総合スコア25327

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

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

saider_san

2020/06/16 07:18

sazi様 コメントありがとうございます! not existsを使えば完結に取れることがわかりました。 とても勉強になりました。 ありがとうございます!
sazi

2020/06/16 07:23

もう一つパターン追加しておきました。
saider_san

2020/06/17 00:11

ありがとうございます!こちらも参考にさせていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問