◎テーブルの説明
SQL
1create table ユーザー( 2 ユーザーCD varchar(12) PRIMARY KEY, 3 氏名 varchar(40) not NULL, 4 電話番号 varchar(20) not NULL 5); 6 7create table 商品( 8 商品No varchar(11) PRIMARY KEY, 9 ユーザーCD varchar(12) , 10 購入日 datetime 11); 12 13create table 識別( 14 識別No varchar(20) PRIMARY KEY, 15 商品CD varchar(7) , 16 商品No varchar(11) 17); 18 19create table 定期( 20 定期No varchar(12) PRIMARY KEY, 21 ユーザーCD varchar(12) 22); 23 24create table 定期商品( 25 定期No varchar(12) PRIMARY KEY, 26 定期商品No int not NULL, 27 商品No varchar(11) 28); 29 30create table 定期履歴( 31 定期No varchar(12) PRIMARY KEY, 32 定期履歴連番 int not NULL, 33 解約フラグ int, 34 定期開始日 datetime, 35 定期終了日 datetime 36);
SQL
1insert into ユーザー values ('100000000001','テスト太郎1','09011112222'); 2insert into ユーザー values ('100000000002','テスト太郎2','09111112222'); 3 4insert into 商品 values ('11111111111','100000000001','2018-12-11'); 5insert into 商品 values ('11111111112','100000000002','2018-12-12'); 6 7insert into 識別 values ('12345678901234567890','MKN1111','11111111111'); 8insert into 識別 values ('12345678901234567891','MKN1111','11111111111'); 9insert into 識別 values ('12345678901234567892','MKN1111','11111111112'); 10 11insert into 定期 values ('555555555555','100000000001'); 12 13insert into 定期商品 values ('555555555555','1','11111111111'); 14 15insert into 定期履歴 values ('555555555555','1','0','2016/1/1','2016/12/31'); 16insert into 定期履歴 values ('555555555555','2','0','2017/1/1','2017/12/31'); 17insert into 定期履歴 values ('555555555555','3','0','2018/1/1','2018/12/31'); 18insert into 定期履歴 values ('555555555555','4','0','2019/1/1','2019/12/31');
※テスト太郎1の持つ商品に付いている定期は、定期終了日が2019/12/31で解約フラグ0なので有効な定期がある。
定期履歴連番3で止まっていたり、定期履歴連番4があっても解約フラグ1なら定期が切れている。
また、テスト太郎2の持つ商品には定期が付いていない。
※「定期履歴」テーブルは「定期」テーブルの下の階層。
例
定期No、定期履歴連番、定期開始日、定期終了日
1,1,2016/1/1,2016/12/31
1,2,2017/1/1,2017/12/31
1,3,2018/1/1,2018/12/31
1,4,2019/1/1,2019/12/31
◎やりたい抽出
商品を持つユーザーについて、「定期」が無いか、切れているユーザーを抽出したい。
「定期」が無いとは・・・そのユーザーについて「定期」テーブルのデータが無い。
「定期」が切れているとは・・・「定期履歴」の解約フラグが1、または定期終了日がシステム日付を過ぎている。
◎途中経過
複雑な構造なので、joinするとユーザがタブったりします。
しかも、「定期履歴」テーブルについては定期履歴連番がMAXのデータを見る必要があります。
例でいうと、連番4の2019/1/1~2019/12/31定期のデータでみたい。
SQL
1select * 2from [商品] 3INNER JOIN [ユーザー] on [ユーザー].[ユーザーCD] = [商品].[ユーザーCD] 4INNER JOIN [識別] on [識別].[定期No] = [商品].[定期No] 5LEFT JOIN [定期] on [定期].[ユーザーCD] = [ユーザー].[ユーザーCD] 6LEFT JOIN [定期商品] on [商品].[定期No] = [定期商品].[定期No] 7INNER JOIN [定期履歴] on [定期履歴].[定期No] = [定期].[定期No] 8 9WHERE 10 11AND ([定期終了日] < 'システム日付' OR [解約フラグ]=1 or [定期].[定期No] IS NULL ) 12AND [定期履歴連番] = (SELECT MAX([定期履歴連番]) from [定期履歴] WHERE [定期].[定期No] = [定期履歴].[定期No]
結合のキーが足りないのか、LEFT JOINの使い方が違うのか、なかなかうまくいきません。
うまくいく方法が分かりましたら、教えていただけないでしょうか。
よろしくお願いします。
回答2件
あなたの回答
tips
プレビュー