◆ INNER JOIN は行数が減るとは限らない
◆ JOIN で絞り込むときは INNER JOIN じゃないと行が残るかも

INNER JOIN でも行は増える

left join や right join だと結合できなくて null になる場合も行が存在します
ですが inner join だと null になるのは消えるので 結合するテーブルそれぞれの行数と比べて減っていくものかと思ってました

ですが 例えばこういうケースでは行数が増えます

a b
======
11 1
12 2
13 3
14 1
15 2
16 3
a b
======
111 1
222 2
333 3
444 1
555 2
666 3
SELECT
t1.a as t1a,
t1.b as t1b,
t2.a as t2a,
t2.b as t2b
FROM t1
INNER JOIN t2 USING (b)
t1a t1b t2a t2b
=====================
11 1 111 1
11 1 444 1
12 2 222 2
12 2 555 2
13 3 333 3
13 3 666 3
14 1 111 1
14 1 444 1
15 2 222 2
15 2 555 2
16 3 333 3
16 3 666 3

JOIN の絞り込みと WHERE の絞り込み

私は絞り込みは WHERE でしかしなくて JOIN には結合のための条件しか書いてませんでした
でも 人によっては JOIN に AND をつなげて 結合するテーブルに関する条件は JOIN に書いてました

WHERE にいっぱい条件が並ぶよりは テーブルごとに絞り込み条件を書くほうが見やすい気がします
でも
やっぱり WHERE のほうが良かったです

テーブル構造がこんなテーブルを用意します
user
id
name

message
id
user_id
text
visible
データは
INSERT INTO user VALUES
(1, 'name1'),
(2, 'name2');

INSERT INTO message VALUES
(1, 1, 'foo', 1),
(2, 2, 'bar', 0);

WHERE で検索すると
SELECT *
FROM user
LEFT JOIN message ON user.id = message.user_id
WHERE user.id = 1
AND message.visible = 1
id name id user_id text visible
1 name1 1 1 foo 1
SELECT *
FROM user
LEFT JOIN message ON user.id = message.user_id
WHERE user.id = 2
AND message.visible = 1
No records found

想像通りの結果です

JOIN になると
SELECT *
FROM user
LEFT JOIN message ON user.id = message.user_id
AND message.visible = 1
WHERE user.id = 1
id name id user_id text visible
1 name1 1 1 foo 1
SELECT *
FROM user
LEFT JOIN message ON user.id = message.user_id
AND message.visible = 1
WHERE user.id = 2
id name id user_id text visible
1 name1 null null null null

message.visible の絞り込みで消えるレコードで動きが変わります
結合条件に visible が 1 とあるので 結合対象が 0 しかない user_id = 2 のレコードは結合できません
LEFT JOIN なので右側のテーブルに結合する行がなくても値が null になって行が残ります
INNER JOIN にすれば消せますが 絞り込みじゃなく結合だけの条件で LEFT JOIN を使いたい場合には INNER JOIN にしてしまえません

そういうことを考えるとやっぱり WHERE に書いたほうがよさそうです