LoginSignup
0

More than 3 years have passed since last update.

RDBのSQLの本質は、行単位に処理している。

Posted at

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0