SQL 入門 > SELECT

SQL 入門 (DMLの基本形式:SELECT)

レコードの取り出し (SELECT: 等号検索、不等号検索、範囲検索、前方一致、後方一致検索)

テーブルからデータを選択、射影する。

SELECT の基本フォーマット

  • 基本的なフォーマット
SELECT [ALL | DISTINCT(UNIQUE)]
{
  * | <列名> [[AS] <列別名>],…
}
FROM
  <表名> [<表別名>] , …
[WHERE <条件式>]
[GROUP BY <式>]
[HAVING <条件式>]
[ORDER BY
   { <列名> | <列番号> } [ASC | DESC] [NULLS FIRST| NULLS LAST], … 
]

GROUP BY と HAVING は両方を指定する場合には、どちらを先にしても良い。
HAVING を単独で使用可能(表全体を1グループとして扱うが Oracle 9i R1 以前のマニュアルの構文上では許されていない)。

SELECT の例文: 等号選択検索

  • 等号による条件 WHERE a = b

ユーザー ID が'0020'の人を検索する。

SELECT * 
  FROM USER_MASTER
 WHERE USER_ID = '0020'

不等号選択検索

  • 不等号による条件 WHERE a {<|<=|<>|>=|>} b

2004/10/01 以降にレコードが作成された人を検索する。
NLS_DATE_FORMAT='RR/MM/DD'の場合

SELECT * 
  FROM USER_MASTER
 WHERE CREATED_ON >= '2004/10/01'

単純比較条件

範囲選択検索 (BETWEEN)

  • BETWEEN による条件 WHERE BETWEEN a AND b 、不等号の AND 条件

BETWEEN 〜 AND 〜 と複数の不等号による範囲指定によるレスポンスの差は限りなくゼロ。(Oracle 10g 時点)

2004/10/01〜10/31 にレコードが作成された人を検索する。

SELECT * 
  FROM USER_MASTER
 WHERE CREATED_ON BETWEEN '2004/10/01' AND '2004/10/31'
 または
SELECT * 
  FROM USER_MASTER
 WHERE CREATED_ON >= '2004/10/01' AND CREATED_ON <= '2004/10/31'

条件は AND / OR で結合して複数記述できる。
AND は算術演算の積算、OR は加算のような演算の優先順位があるので、括弧を使用して優先順位を指定する。

条件A OR 条件B AND 条件C ⇒ 条件A OR ( 条件B AND 条件C) になってしまう。
(条件A OR 条件B) AND 条件C などと記述する。

col BETWEEN a AND b と col >= a AND col <= b

少なくとも現在では(かなり過去から)全く同じとして取り扱って問題ない。

Oracle 6〜7 の頃にどちらか一方ではインデックスが使われないから遅くなるという噂は少なからずあったと記憶している。
BETWEEN は一文なので SQL が短いし、根拠すらわからないが比較が1回になるから BETWEEN を使う。といったルールも聞いたことがある。どんなコンパイラなのだろう…

また本来の用法ではないトリッキーな SQL によるチューニング手法や TIPS は コストベース・オプティマイザ にとって本当の使用目的から外れた SQL で書かれることもある。
トリッキーな手法ほど Oracle のバージョンアップで高速化できる可能性の摘み取る結果になる(と思う)
一般的でわかりやすい・読みやすい SQL に対して注ぐことに務める方をおすすめする。

前方一致、後方一致 検索 (LIKE)

  • WHERE LIKE {ワイルドカード付き文字列}

LIKE で指定できるワイルドカードは以下、任意の場所に幾つでも置ける。

パーセント(%) は任意の0文字以上文字列をあらわす。
アンダースコア(_) は任意の1文字をあらわす。

明記はないが %,_ ともに全角、半角を問わない。 (Oracle 10g 時点)

名前が'小泉'で始まる人を検索

SELECT * 
  FROM USER_MASTER
 WHERE USER_NAME LIKE '小泉%'

名前が'太郎'で終わる人を検索

SELECT * 
  FROM USER_MASTER
 WHERE USER_NAME LIKE '%太郎'

ワイルドカードを含む LIKE 検索(エスケープ文字を'\'に登録')
'dummy%' で終わる人を検索

SELECT * 
  FROM USER_MASTER
 WHERE USER_NAME LIKE '%dummy\%' ESCAPE '\'

引用符を検索

単一引用符(') を条件に含める
あいう'えお を検索

正しい例

-- 単一引用符を 2つ連続して記述
SELECT * 
  FROM USER_MASTER
 WHERE USER_NAME = 'あいう''えお' ;
-- または 引用符を再定義する。10g
SELECT * 
  FROM USER_MASTER
 WHERE USER_NAME = q'{あいう'えお}' ;

引用符を定義する方法は、他にも色々な形式がある。⇒ 代替引用符

失敗例 その1 (前述のエスケープ文字では表現できません)

SELECT * 
  FROM USER_MASTER
 WHERE USER_NAME = 'あいう\'えお' ESCAPE '\' ;
 
ORA-01756: 引用符付き文字列が正しく終了していません

失敗例 その2 (二重引用符(") は文字列として Oracle に理解されない)

SELECT * 
  FROM USER_MASTER
 WHERE USER_NAME = "あいう'えお" ;
 
ORA-00904: "あいう'えお": 無効な識別子です。

識別子とはカラム名やテーブル名などのオブジェクト名をあらわすもの。

多値検索 (≒ OR 検索)

  • 同じカラムを多数の値(式)条件で検索

ユーザー ID が '0001', '0002' '0003' の人を検索

SELECT * 
  FROM USER_MASTER
 WHERE USER_ID IN ('0001' , '0002', '0003')

他にも ANY、ALL がある。
例)

= ANY ( a, … )       ⇔ IN ( a, … )と同じ
>= ANY ( 10, 20, … ) ⇔ 10, 20, … のいずれか以上
= ALL ( a, … )       ⇔ a, … とすべて一致
<= ALL ( 10, a+b, … )  ⇔ 10, a+b … のすべて以下

グループ比較条件



関連事項

 
日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ オラクルサポートセンター