SQLのLEFT JOINで初心者の時に気をつけておいたほうがいいこと
sqlのleft joinの動きをあまり理解していない時に間違った結合してしまいがちでしたので、その時に解決した方法です。
MySQL使ってます。 以下のテーブルでみます。
CREATE TABLE `tiku` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `taisyo_flg` int DEFAULT 0 NOT NULL, PRIMARY KEY (`id`) ) DEFAULT CHARSET=utf8mb4; insert into tiku values (null,'北海道',1), (null,'関東',1), (null,'関西',0), (null,'近畿',1), (null,'九州',0); CREATE TABLE `customer` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `tiku_id` int unsigned NOT NULL, `name` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) DEFAULT CHARSET=utf8mb4; insert into customer values (null,1,'田中'), (null,1,'佐藤'), (null,1,'佐々木'), (null,2,'鈴木'), (null,2,'村田'), (null,3,'木村'), (null,4,'前田'), (null,5,'吉田'), (null,5,'田村')
まず普通に顧客テーブル(customer)に、地区テーブル(tiku)を外部結合して、顧客に対する地区の情報を見る
それに対して、顧客名は全て出力するが、 地区名は、taisyo_flgが1のものについては、地区名を表示し、 taisyo_flgが0のものについてはNULLで出力したい場合があるとする。
select * from customer left join tiku on customer.tiku_id=tiku.id where tiku.taisyo_flg = 1
上のようにwhereで絞る方法では、当然、taisyo_flgが1のものだけが選ばれてしまい、 顧客名を全て出力するという条件を満たせません
とりあえず私の中では2つ方法があるかと思いました。
1. left joinのジョインキーの部分でやる
select * from customer left join tiku on customer.tiku_id=tiku.id and tiku.taisyo_flg = 1 order by customer.id
ジョインキーはandで複数指定できるので、 andでtiku.taisyo_flg=1とすれば、顧客名を全て出しつつ、taissyo_flgが1のものだけ地区名を出す動きになってくれるようです。
2. サブクエリにする
select * from customer left join ( select * from tiku where taisyo_flg = 1 ) tiku on customer.tiku_id=tiku.id order by customer.id
個人的には、こっちのやり方のほうが見た目どういう動きかわかりやすいと思います。 サブクエリでwhere taisyo_flg = 1と絞っているので、そこに外部結合してもtaisyo_flgが0のものは持って来ようがないという感じで。
SQLをちょっと勉強したという時は、この辺の動作がわかりにくかったのを思い出して書かせていただきました。 最後まで読んでいただきありがとうございました。