SELECT文を考える時、何となくjoinやgroup byとか使ってませんか?もしくはメインとなるテーブルを意識していますか?
SELECT文は非常に便利なので気づかないのですが裏で実行されている事は(非常に簡単に言うと)
・縦*横の二次元の表を付きあわせ、新たな縦*横の二次元の表を作成
しているだけなのです。
その際に、一行の粒度が変わる事に注意が必要です。多重度が大きい側にjoinすると、自ずと一行の粒度が変わってしまう(行が増えてしまう)為、初心者のうちは自分が何をしているのか分からなくなります。
例えば次のER図があり、
最終的に次のような表が欲しい場合、どういうSQLを書きますか?
私は概ね次のステップでSELECT文を考えます。
・最終アウトプットの一行の粒度を確認する。
この場合注文明細の行数が最終アウトプットの行数と同じ
・その粒度にあったテーブルをメインの表にする。
from 注文明細を起点に考える
・そこに枝葉のテーブルを加える。その時に行の粒度を変えない(膨らまさない)。
from 注文明細
inner join 注文 on 注文.注文番号 = 注文明細.注文番号
inner join 顧客 on 顧客.顧客NO = 注文.顧客NO
inner join 商品 on 商品.商品NO = 注文明細.商品NO
from 注文からはじめる人も多いと思いますが、注文明細をjoinした時に行が膨れるため、考えを単純化する目的で、こんな簡単な場合でも徹底して明細側をメインテーブルにします。
あまりにも意図せず膨らましてしまい、group by/distinctでお茶を濁そうとする人が多そうなので記事にしてみました。もちろん集計が入ってくるとこの限りでは無いのですが、「最終アウトプットの一行の粒度」を意識する事は非常に重要です。
0 件のコメント:
コメントを投稿