SQLがよく分からん。
って思っていたころ、
SQLは、
「行単位に処理しているだけじゃん。」
って言われて、衝撃を受けたので、その話をします。
SQLがいまいち腹落ちしていない人向けの記事になります。
pk | test_val1 | del_flg |
---|---|---|
1 | a | 0 |
2 | a | 1 |
3 | i | 0 |
こんな表があったとします。
# 業務上、こんな表はあり得ませんw
が説明のための表なのでご容赦ください。
このうち、test_val1を重複なく、有効な行を取得したい
要するにこんな行。「a」は、「del_flg」が「1」の行があるので除外して取得した。
pk | test_val1 | del_flg |
---|---|---|
3 | i | 0 |
って思った時、どう取得するかというと、
select t1.pk, t1.test_val1 from test t1
where not exists(select * from test t2
where t1.test_val1 = t2.test_val2
and t2.del_flg = '1'
)
もしくは、
select t1.pk, t1.test_val1 from test t1
where t1.test_val1 not in (select * from test t2
where t1.test_val1 = t2.test_val2
and t2.del_flg = '1'
)
な感じ。
何を言いたいかというと、SQL上、testテーブルが「2回」出てきます。
同じテーブルなのに、「2回」出てきます。
SQL上、「1回」だけでは判定が出来ないのです。
それは、SQLの動きが、
「1行ずつ抽出対象か判定」
していく為です。
このため、「自分の行以外」を「抽出条件にする場合」は、
同じテーブルであっても、SQL上、「別テーブル」として「もう1回定義」しなくてはいけません。
pk | test_val1 | del_flg |
---|---|---|
1 | a | 0 |
2 | a | 1 |
3 | i | 0 |
動きとしては、こんな感じ。
1.「PK=1」を抽出するか判定する。そのために、別テーブルと定義されている「PK=1、PK=2、PK=3」を参照する。
2.「PK=2」を抽出するか判定する。そのために、別テーブルと定義されている「PK=1、PK=2、PK=3」を参照する。
3.「PK=3」を抽出するか判定する。そのために、別テーブルと定義されている「PK=1、PK=2、PK=3」を参照する。
さらに言えば、1、2、3の回数を決めるテーブルを「駆動表」と呼びますね。
どの表を基に、SQLを駆動させるか?ということで、駆動表。
まあ~、チューニングの世界になるので、それはさておき。
SQLは、結局、行単位に処理をしている。
ただ、それだけ。
それを忘れなければ、どんなSQLも読めます。
※ RDBに限った話ですw NOSQLとかは別の話ですw