SQLをより賢く使うための12のヒント

文:Susan Harkins  翻訳校正:石橋啓一郎
2009-06-30 08:00:00
  • このエントリーをはてなブックマークに追加

10: SELECT INTOではコピーできないプロパティ

 SQLのSELECT INTOは、次のような形で既存のテーブルからレコードをコピーして新しいテーブルを作成する。

SELECT list|* INTO newtable

FROM sourcetable

[WHERE condition]

 しかし、このステートメントはテーブルを完全にコピーしてくれるわけではない。このステートメントは元のテーブルの主キー、インデックス、カラムとテーブルのプロパティは(デフォルトの設定以外は)コピーしてくれない。それに加え、Captionプロパティは無視され、元のカラムの名前が使われる。

 SELECT INTOステートメントを使用する際には、スコープ内に新しいテーブルと同名のテーブル(newtableがすでに存在する場合、このステートメントは既存のテーブルを置き換えるということを念頭に置いておく必要がある。幸運なことに、SQLは最初に警告してくれる。一部のケースでは、エンジンは実際に新しいテーブルを作成する前に既存のテーブルを削除してしまう。この場合、何かまずいことがあっても元のテーブルがなくなってしまっているため、それに頼ることができない。もしnewtableがすでに存在するのであれば、SELECT INTOを実行する前にコピーを作っておいた方がいいだろう。また、この際にnewtableがオープンされている場合、SQLはエラーを返す。

 新しいテーブルにデータをコピーする必要がないのであれば、次のようにWHERE句を追加して新たに空のテーブルを作ることもできる。

SELECT * INTO newtable

FROM source

WHERE FALSE

 この場合、SQLはnewtableを作成するが、条件にはFALSEが指定されており、これを満たすことのできるレコードは存在しないため、データはコピーされない。

11: WHEREとHAVINGの違い

 WHERE句とHAVING句は似た機能を持っているが、同じものではない。WHEREはSELECT句が返すデータを制限するものであるため、GROUP BYは重要ではない。エンジンはデータを比較し、グループ化を行う前にWHERE句の条件を満たさないレコードを切り捨てる。一方で、HAVING句はグループ化の条件を満たさないデータを切り捨てる。

 どちらの句を使うかがよく分からないという人は、WHERE句はGROUP BY句の前に置かれているので、エンジンはレコードのグループ化を行う前にWHERE句を適用するという風に覚えておけばいいだろう。

12: UNIONの注意点

 SQLのUNION操作は、次のような形で、異なるクエリやテーブルの結果得られるレコードを結合する。

SELECT1 list|*

UNION 

SELECT2 list|*

 UNIONについて覚えておくべき重要なことは、両方のSELECT句のカラム順が一致しなくてはならないということだ。カラム名が一致する必要はないが、どちらのリストにも同じ数のカラムがなくてはならず、データ型も適合していなくてはならない。データ型が一致しない場合、エンジンがもっとも合う型を選択する。その結果はうまくいくかも知れないが、うまくいかないかも知れない。

 デフォルトではUNIONはレコードを最初のカラムの値によって並び替える。これは、UNIONが暗黙のうちにDISTINCT述語を使って、重複するレコードを省くためだ。重複しているものも含めて、すべてのレコードを含めるためには、UNION ALLを使用すればよい。これを使った場合、暗黙のうちに行われている並べ替えは実行されなくなる。重複レコードは存在しないことをあらかじめ知っており、レコードの数が非常に多い場合も、UNION ALLを使うことで性能を向上させることができる。これは、エンジンが(重複を見つけるために)必要な並べ替えの処理を飛ばすためだ。

この記事は海外CBS Interactive発の記事をシーネットネットワークスジャパン編集部が日本向けに編集したものです。 原文へ

このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。 これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。
Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。
[ 閉じる ]