SQL クエリのスタイル、もしくは、 なぜ SQL クエリは読みにくいのか
しばらくの間、 SQL で書かれた、様々な集計クエリを読んでいたのですが。どうも、クエリが読みにくくていけない、と思いまして、いまさらながらですが、 SQL クエリの書き方について考えました。
SQL クエリの読みにくさの原因というのは、いくつかあるのですが、一番大きいのは、 FROM 句と、 WHERE 句が離れてしまうことにあると思います。クエリを作るときには、テーブル/リレーションごとに条件を考えて、クエリを組み立てていくと思います。これを、 昔ながらのスタイルで SQL に書くと、 FROM 句にリレーションが並び、 WHERE 句にリレーションの条件が並ぶ、という、リレーションと条件とが分離した形になります。
クエリの読み手がクエリを読む際には、 クエリを作るときの手順を逆に行なうことになります。 WHERE 句に並んでいる条件が、 FROM 句のどのリレーションにかかっているのか、 FROM 句のリレーションごとに、 WHERE 句の条件を並べなおして、クエリからどのような結果が出力されるかを読み取ろうとするわけです。
このようなクエリは、例えば、以下のようなものになります 1 。
select a.A_ID, trim(a.A_LNAME) || ',' || trim(a.A_MNAME) || ',' || trim(a.A_FNAME) as a_name, ol.OL_QTY from CUSTOMER c, ADDRESS ad, COUNTRY co, ORDERS o, ORDER_LINE ol, ITEM i, AUTHOR a where ad.ADDR_ID = c.C_ADDR_ID and co.CO_ID = ad.ADDR_CO_ID and co.CO_NAME = 'Japan' and o.O_C_ID = c.C_ID and o.O_STATUS = 'SHIPPED' and ol.OL_O_ID = o.O_ID and i.I_ID = ol.OL_I_ID and i.I_PUB_DATE >= date '2007-08-01' and i.I_PUB_DATE < date '2009-09-01' and a.A_ID = i.I_A_ID and c.C_DISCOUNT >= 0.1 order by A_ID
このように、いちいち、 WHERE 句と、 FROM 句を頭の中で照合するのは、リレーションの数、条件の数が増えてきますと、やっておれなくなってきます。このため、別途、メモを作成して、リレーションごとに条件をまとめてみたりするわけですが、 無用な手間、という感じなんですよね。
そこで、私がこうしたクエリを書くときにやるのが、 WHERE 句にある条件を、すべて JOIN 句に書く、というやり方です。 さらに、 FROM 句の一番目のテーブルの条件だけは、 WHERE 句に残ってしまうため、あえて、サブクエリにします。
こうしますと、条件がリレーションごとにまとまりますので、かなり読みやすくなるのではないかと思います。
select a.A_ID, trim(a.A_LNAME) || ',' || trim(a.A_MNAME) || ',' || trim(a.A_FNAME) as a_name, ol.OL_QTY from ( select C_ID, C_ADDR_ID from CUSTOMER where C_DISCOUNT >= 0.1) c inner join ADDRESS ad on ad.ADDR_ID = c.C_ADDR_ID inner join COUNTRY co on co.CO_ID = ad.ADDR_CO_ID and co.CO_NAME = 'Japan' inner join ORDERS o on o.O_C_ID = c.C_ID and o.O_STATUS = 'SHIPPED' inner join ORDER_LINE ol on ol.OL_O_ID = o.O_ID inner join ITEM i on i.I_ID = ol.OL_I_ID and i.I_PUB_DATE >= date '2007-08-01' and i.I_PUB_DATE < date '2009-09-01' inner join AUTHOR a on a.A_ID = i.I_A_ID order by A_ID
というわけで、 私は、 WHERE 句ではなく、 JOIN 句に条件を書く、というスタイルを推奨してみたいわけです。
1. データベース・スキーマは、 OSDL DBT-1 より。
| 固定リンク
| コメント (0)
| トラックバック (0)
最近のコメント