UNIONとORDER BYに関するSQLの事実
UNIONとORDER BYは強力なSQL機能ですが、それら2つを一緒に使用すると、おかしな、いらだたしいエラー メッセージが表示されることがあります。DB2 for iプロフェッショナルである我々にとって幸いなことに、これら2つを連携させて使用する簡単な方法があります。今日は、それらを理解することができる絶好の日になります。
例として、一部のクエリーで、顧客マスターテーブル(ファイル)とベンダー マスターテーブルを使用します。これらは、とある企業の取引先であるため、それら2つのテーブルには、特に名前や住所など、多くの共通する属性があります。また、2つの売上履歴テーブル(2015年と2016年で1つずつ)も使用します。企業では一般に、変化しないサマリー データに迅速にアクセスするために、そのようなテーブルを使用します。そのようなテーブルには、同じデータが様々な形式(たとえば、月間売上、四半期売上、年間売上)で入れられることになります。以下の例では、年間売上を使用します。
次の表は、これらのデータベーステーブルの列(フィールド)名を示しています。
CUST | VENDOR |
CUSTNBR | VENDORID |
NAME | NAME |
CITY | CITY |
STATE | STATE |
ZIP | ZIPCODE |
SALES2015, SALES2016 |
CUSTNBR |
YEARLY |
(他の列は省略) |
事実1: ORDER BYは最後の副選択の後に置けば、結合全体に適用されます。
よくありがちな間違いは、ORDER BY節を副選択ごとに置いてしまうことです。そのようにすることは許容されません。不必要なためです。システムはすべての副選択からの結果セットを結合してから、結合されたデータをソートします。次の例では、取引先が、州、都市の順番に取り出されます。
事実2: すべてのコンポーネントの結果セットにある列名でソートできます。たとえば、取引先のデータを結合する場合は、NAME、CITY、およびSTATEでソートできます。
事実3: 列名が別の副選択で別の名前になっている場合、許容される列名を生成するためには、それらの1つまたは複数の列の名前を変更する必要があります。次のクエリーでは、ベンダー表のZIPCODE列の名前をZIPに変更します。
事実4: ORDER BY節で列番号を使用することができます(これは、結合をソートする際の私のお気に入りの方法の1つです)。この場合、列名はすべての副選択を通じて一貫性のある名前である必要はありません。次の例では、顧客テーブルではZIP、ベンダーテーブルではZIPCODEである、5番目の列でデータを並べ替えします。
事実5: UNIONを使用して表を作成するときに、列番号を使用することはできません。列番号を使用するのではなく、必ず、すべての副選択を通じて一貫性がとれるように列に名前を付ける必要があります。これを行う方法は2通 りあります。
1つ目は、相関名を使用する方法です。
2つ目は、CREATE TABLEコマンドで列を列挙する方法です。
事実6: 式を括弧で囲むことで、コンポーネントのSELECTでORDER BYを使用することができます。これが意味を成す唯一の時は、行選択に役立てるためにORDER BYが必要となる時です。2015年および2016年の上位2件の顧客を検索します。
その他の結合の場合と同じように、最終的な結果セットをソートするために、結合全体に対してもう1つのORDER BY節を追加することができます。
事実7: 結合を並べ替えするときに式を使用することはできません(これにはがっかりです)。
システムは非情にも「ORDER BY expression is not valid.(ORDER BY式は無効です。)」というメッセージで応答します。いつかはできるようになるかもしれません。 そう願いたいものです。
事実8: これらの法則はINTERSECTおよびEXCEPTにも当てはまります。UNIONと異なり、あまり頻繁に用いられると思われないため、それらの例はここでは取り上げませんでした。
結論:おかしなエラーメッセージが表示されても、うろたえないことです。ほとんどの場合、それらを回避する方法を見つけることができます。
【 あわせて読みたい記事 】