■ 概要
SELECT文とは、SQL文の4種類の分類
「DML、DDL、DCL、トランザクション制御」のうち
DML(データ操作言語)に分類される、データをDBから取り出す際に使用するSQL言語である
SELECT文の3つの機能
・射影:特定の「列」のデータのみ取り出す
⇒つまり「カラム名」を指定して取り出す
・選択:特定の「行」のデータのみ取り出す
⇒つまり「フィールドの値」を指定して取り出す
・結合:複数のテーブルを列のデータで関連付けて取り出す
これらはテーブル結合し(結合)、とある値を指定して(選択)、特定のカラムのデータを取り出す(射影)というように組み合わせても使用する
■ データ抽出の記述方法
SELECT文の基本的な記述は
「SELECT 何を FROM どのテーブルから」
・すべてのデータを取得
SELECT * FROM テーブル名
・指定のカラムのデータを取得
SELECT カラム1,カラム2(カンマで区切る)
⇒カラム名を確認する際は
「DESCRIBE テーブル名」でテーブルに定義されているカラムの情報を一覧で確認できる
・算術式を指定し計算結果を取得
列名、定数値(リテラル)に対して算術演算子(+,-,*,/)を用いることで計算した結果を取得できる
※リテラル:内容によって文字、日付、数値リテラルに分かれる
⇒算術式の中に1つでもNULL値が含まれていると、その計算結果はNULLとなる
例えば
SELECT カラム1 + カラム2 FROM テーブル名
としたときに
とあるレコードのカラム1の値が1,000、カラム2の値が500の場合、1,500という値が取得できるが
カラム1が1,000、カラム2がNULLの場合、結果は1,000でなくNULLとなる
・列別名の指定
取得したデータの列名、算術式は、通常すべて大文字で表示されるが、変更可能
1.SELECT カラム1(算術式) 列別名
2.SELECT カラム1(算術式) AS 列別名
列別名は
1.スペースや特殊文字(#、$など)を使用する場合
2.大文字、小文字を区別する場合
"列別名" と二重引用符で囲む必要がある
・連結演算子「 || 」で列値、リテラルを結合
SELECT name || 'さんは' hiredate || '入社です'
FROM テーブル名
というように連結演算子で列値やリテラルを結合できる
リテラルは一重引用符(' ')で囲む
⇒SELECT文だけでなく、SQL文全体でリテラルは一重引用符で囲むルール
二重引用符で囲むのは列別名なので混同しないよう注意
⇒リテラルに一重引用符を使用したい場合は、「代替引用符演算子(q)」を使用する
SELECT name || q'【's Salary】'
【】のような'を文字として使用したいリテラルを囲むものを「引用符デリミタ」という
引用符デリミタは【】、{}、()、<>や、任意のシングル、ダブルバイトの文字を指定できる
・DISTINCTを用いた重複行の排除
SELECT DISTINCT カラム1
FROM テーブル名
上記のようにSELECTとカラム名の間にDISTINCTを記述すると、そのカラム内で重複する行が排除され表示される
またカラムが複数の場合、例えばカラム1,カラム2を取得する場合、カラム1の値が同じでも、カラム2の値が異なれば取得される
■ WHERE句を使用した条件の絞り込み
FROMの後に「WHERE 条件」を記述することで条件を絞ってデータが取り出せる
条件部分は、列名 比較演算子(=、>、<=、IN、LIKEなど)
※列別名を指定することは不可
比較演算子を使用した条件のことを「比較条件」という
WHERE句の条件に指定する文字リテラルは、前述のとおり一重引用符(' ')で囲む
WHERE yomi = 'suzuki'
また指定した文字リテラルは大文字、小文字が区別されるため、「'SUZUKI'」とすると小文字のデータは取得されない
日付リテラルを指定する場合は「日付書式」による記述が必要「21-04-14」のように「RR-MM-DD」で表記
「等しくない場合」を条件指定する場合は
<>、!=、^= のいずれかを使用する
・BETWEEN演算子
WHERE 列名(算術式)BETWEEN 下限値 AND 上限値
BETWEEN 下限値a AND 上限値b ⇒ a以上b以下(aとbは含む)
NOT BETWEEN 下限値a AND 上限値b ⇒ a未満、またはbを超過(aとb
は含まない)
NOTがつくと境界値は取り出す範囲に含まれない
また下限値と上限値を入れ替え
BETWEEN 上限値 AND 下限値 とした場合は、存在しない数字(例えば2以上1以下など)を指定していることとなり結果は0となる(エラーは出ない)
・IN演算子
WHERE 列名(算術式) IN(値1,値2)
指定した値1、値2のいずれかと等しい場合にTRUEでデータを取り出す
NOT IN(値1,値2)で、いずれとも等しくないデータを取り出す
文字リテラルも指定できるが、IN('営業部','管理部')のように、既述の通り一重引用符が必要
・LIKE演算子
ワイルドカード( % , _ )を使用して、指定した文字のパターンに一致するデータを取得
キーワード検索的なイメージ
WHERE name LIKE '%ペン' と、頭に%をつけると
ボールペン、蛍光ペン、筆ペンのような○○ペンというデータが取得される
WHERE name LIKE 'ペン%' と、終わりに%をつけると
ペン立て、ペンケース、ペンライトにようなペン○○というデータが取得される
WHERE name LIKE '%ペン%'と、両方に%をつけると、「ペン」という文字列を含むすべてのデータが取得される
%は「0文字以上の任意の文字列」を指定する
一方 _ は「任意の1文字」を指定するため
WHERE name LIKE '_ _ ペン' とすると、計5文字のため
蛍光ペンや筆ペンは取得されず、ボールペンが取得される
WHERE name LIKE ' _ _ _ _'とすると、5文字のデータすべてが取得される
% と_ を組み合わせて使用も可能
WHERE name LIKE '% _ _ _ ペン' とすると、5文字以上の○○ペンが取得される
また100%や、a_b など、%と _ を文字リテラルとして使用する場合は「ESCAPEオプション」を設定する
エスケープ文字(¥、$、#、aなど任意の1バイトの文字)を指定する
WHERE name LIKE '100¥%%' ESCAPE '¥'
エスケープ文字 ¥ の後の%は文字リテラルとして識別され、後に続く%がワイルドカードとして認識される
エスケープ文字は、文字リテラルとして扱いたいワイルドカードごとに指定する必要があるため、例えば「 100%_ 」で始まるデータを取得したい場合は
WHERE name LIKE '100¥%¥_%' ESCAPE'¥'
とする
・IS NULL演算子
列にNULL値が含まれる値を取得する
WHERE comm IS NULL
IS NOT NULLでNULL値が含まれない値を取得
※NULL値は特殊な値であり、IS (NOT) NULL演算子のみでしか比較(含まれるかどうか)できないため、
WHERE comm = NULL
のように、比較演算子を使用した記述ではデータ取得ができない
しかしエラーにもならないため注意
・論理演算子
WHERE 条件1 AND 条件2:どちらの条件も満たすデータを戻す
WHERE 条件1 OR 条件2:どちらかの条件を満たすデータを戻す
WHERE NOT 条件:条件を満たさないデータを戻す
OR演算子はIN演算子で書き換え可能
WHERE 列1 = 値1 OR 列1 = 値2 OR 列1 = 値3
⇒ WHERE 列1 IN(値1,値2,値3)
⇒実行時のパフォーマンスはどちらでも変わらない
ここまでの各演算子の優先順位は
・算術
・結合
・比較
・IN,LIKE,NULL
・BETWEEN
・等しくない(!=,^=,<>)
● NOT演算子
● AND演算子
● OR演算子
・置換変数
SQL*PLUSでは置換変数を使用することで、WHERE句の条件に指定する値を、SQL文の”実行時に”指定して置き換えることができる
&置換変数:SQL文の実行時に置き換える値の入力が要求される 実行後に指定した値は破棄される
&&置換変数:👆要求され置き換えた値がSQL文実行後も保持される
⇒WHERE deptno = &deptno とすると
「deptnoに値を入力してください:」と要求が出る
&&置換変数で置き換えた値は
DEFINE 変数名 でセットされている値を確認し
UNDEFINE 変数名 でセットされている値を削除することができる
■ ORDER BY句を使用した並べ替え(ソート)
SELECT 列名,列名…
FROM テーブル名
WHERE 条件
ORDER BY 列名,列名…
上記のようにORDER BY句はSELECT文の最後に記述する
※SQL行制御を使用する場合はさらに別の句が後ろに指定される
ORDER BY に続くソートしたいデータの指定は、列名の他
・式(Sal * 12など、年収換算してソート)
・列の位置(文冒頭 SELECT number,name,job で name を指定したい場合は数字の「2」)
・列別名
などを指定することができる
SELECT句に指定していない列でもORDER BY句で指定可能だが、取得結果にはORDER BY句でのみ指定した列は表示されない
⇒SELECT number,name でソートを ORDER BY department とすると
部署の昇順にソートされたnumber,nameのデータのみが取得される
※後に見て分かりにくいため実務ではあまり使用しないが、エラーにならないということは理解が必要
ソート順はデフォルトで昇順(ASC)
数値 ⇒ 小さい数値から
日付値 ⇒ 古い日付から
文字値 ⇒ アルファベット順、続いて50音順
NULL値 ⇒ 最も大きい値として扱われる
DESCの記述で降順にすることも可能
⇒ ORDER BY hiredate DESC だと入社日の新しい順
NULL値のソート順を制御するには、NULL FIRST または NULL LAST を指定する
ORDER BY comm NULL FIRST とすると、NULL値を含む行が取得データの先頭に来る
ORDER BY句とWHERE句は同時に使用可能(WHERE句が必ず先)
部署名を絞って、番号順に並べ替え のような使い方
・複数の列をソートに指定した場合
ORDER BY sal * 12 , deptno DESC のように複数指定した場合は、指定した順番でソートされる
つまり年収を昇順でソートした後、同額のデータについては部署番号の降順で並べ替える
・SQL行制御
SELECT文の結果として戻される「行の数」を制御する機能(12cから追加)
行数の制御には、行制限の条件「row_limiting_clause」を記述する(先述したように唯一ORDER BY句の後ろに記述する)
内容は
・OFFSET句:スキップする行を指定、省略すると最初の行から取得
行数の後に「ROW、またはROWS」をつける
OFFSET 5 ROWS とすると取得データの先頭5行をスキップし、6行目から取得される
※格納されているデータ数以上の数値 or NULL値を指定した場合は、返されるデータは0(エラーにはならない)
・FETCH句:取得する行の数、または割合を指定、省略するとすべての行を取得
FETCH FIRST (NEXT) 5 ROWS (ROWS) ONLY (WITH TIES)
⇒FIRST,NEXTはどちらでも可(省略は不可)、5行を指定し、ONLYは確実に5行、WITH TIESは5行目と同じソートキーの行も一緒に取得する(例えばSalを昇順で5行取り出した際に、5行目と6行目の数値が同じだった場合に6行目も取り出す 7行目、8行目も同じだった場合は行数制限なく取り出す)
FETCH FIRST (NEXT) 50 PERCENT ONLY (WITH TIES)
⇒50 PERCENTは行制限の条件前に指定した条件で絞り込んだデータ数の50%を表示する
WHERE deptno = 10 で絞り込んだ件数が20件だとすると、そのうち10件を表示する