0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SELECT文によるデータの取得方法

Posted at

■ 概要

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件を表示する

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?