テーブルからデータを取り出す SELECT 文を学びます。SQL の中で最も多く使う文です。表示する列を選び、並べ替え、重複をなくし、列の値を使って計算する、という SELECT の基本の形を身に付けます。この章では、ワークシートのタブに XE_DBAPP と表示されていることを確認してから、SQL を1つずつ Ctrl + Enter(文の実行)で実行してください。
この章で学ぶこと
-
SELECT 列名 FROM テーブル名の形と、* -
ORDER BYで並べ替える(昇順・降順、複数の列) -
ASで列に別名を付ける -
DISTINCTで重複をなくす - 列の値を使った計算
5.1 SELECT の基本の形
SELECT 文は、次の形で書きます。
SELECT 列名1, 列名2, ...
FROM テーブル名;
-
SELECTの後ろに、表示したい列 を,で区切って書きます -
FROMの後ろに、どのテーブルから 取り出すかを書きます
結果は、指定した列だけを持つ表の形で返ってきます。第4章で使った SELECT * FROM EMPLOYEE の *(アスタリスク)は、「すべての列」という意味です。
SELECT * FROM EMPLOYEE;
| EMP_ID | NAME | GENDER | AGE | BIRTH_DATE | DEPT_ID | ADDRESS |
|---|---|---|---|---|---|---|
| 1 | 雷禅 海皇 | 1 | 26 | 2000-06-22 00:00:00 | 2 | 大阪府 |
| 2 | 院照 心愛 | 2 | 27 | 1999-07-11 00:00:00 | 1 | 京都府 |
| 3 | 林檎 星飛 | 1 | 24 | 2001-12-24 00:00:00 | 3 | 東京都 |
| 4 | 田中 美咲 | 2 | 24 | 2002-03-05 00:00:00 | 3 | 愛知県 |
| 5 | 佐藤 健太 | 1 | 31 | 1995-04-12 00:00:00 | 2 | 東京都 |
| 6 | 鈴木 花子 | 2 | 29 | 1997-01-30 00:00:00 | 1 | 大阪府 |
| 7 | 高橋 翔 | 1 | 35 | 1991-08-15 00:00:00 | 3 | 東京都 |
| 8 | 伊藤 さくら | 2 | 22 | 2004-05-20 00:00:00 | 2 | 兵庫県 |
| 9 | 渡辺 大輔 | 1 | 42 | 1984-02-10 00:00:00 | 2 | 神奈川県 |
| 10 | 中村 結衣 | 2 | 26 | 2000-09-03 00:00:00 | 3 | 京都府 |
【ご注意】ORDER BY を書かないと、順番は決まっていない
上の結果は社員IDの順に並んでいますが、これは たまたま です。ORDER BY(5.3)を書かない SELECT の結果の順番は決まっておらず、データの量や状況によって変わることがあります。順番に意味があるときは、必ず ORDER BY を書いてください。この章の結果の表は、順番が分かりやすいように、ORDER BY EMP_ID を付けた結果を載せている箇所があります。
5.2 列を選んで取り出す
すべての列ではなく、必要な列だけを取り出してみましょう。氏名と年齢だけを表示します。
SELECT NAME, AGE FROM EMPLOYEE ORDER BY EMP_ID;
| NAME | AGE |
|---|---|
| 雷禅 海皇 | 26 |
| 院照 心愛 | 27 |
| 林檎 星飛 | 24 |
| 田中 美咲 | 24 |
| 佐藤 健太 | 31 |
| 鈴木 花子 | 29 |
| 高橋 翔 | 35 |
| 伊藤 さくら | 22 |
| 渡辺 大輔 | 42 |
| 中村 結衣 | 26 |
列は、書いた順に表示されます。SELECT AGE, NAME FROM EMPLOYEE と書けば、年齢・氏名の順になります。テーブルの列の順とは関係ありません。
【便利な使い方】現場では * ではなく列名を書く
SELECT * は入力が楽ですが、業務のプログラムに書く SQL では、必要な列名を書く のが原則です。不要な列まで取り出すと無駄が増え、後からテーブルに列が増えたときに結果の形が変わってプログラムが動かなくなるおそれがあるからです。* は、SQL Developer でテーブルの中身をざっと確認するときに使います。
5.3 並べ替える:ORDER BY
ORDER BY 列名 を文の最後に付けると、その列の値で並べ替えられます。年齢の小さい順に並べてみましょう。
SELECT NAME, AGE FROM EMPLOYEE ORDER BY AGE;
| NAME | AGE |
|---|---|
| 伊藤 さくら | 22 |
| 林檎 星飛 | 24 |
| 田中 美咲 | 24 |
| 雷禅 海皇 | 26 |
| 中村 結衣 | 26 |
| 院照 心愛 | 27 |
| 鈴木 花子 | 29 |
| 佐藤 健太 | 31 |
| 高橋 翔 | 35 |
| 渡辺 大輔 | 42 |
昇順と降順
小さい順(昇順)が既定で、ASC と書いても同じです。大きい順(降順)にするには、列名の後ろに DESC を付けます。
SELECT NAME, AGE FROM EMPLOYEE ORDER BY AGE DESC;
| NAME | AGE |
|---|---|
| 渡辺 大輔 | 42 |
| 高橋 翔 | 35 |
| 佐藤 健太 | 31 |
| 鈴木 花子 | 29 |
| 院照 心愛 | 27 |
| 中村 結衣 | 26 |
| 雷禅 海皇 | 26 |
| 田中 美咲 | 24 |
| 林檎 星飛 | 24 |
| 伊藤 さくら | 22 |
年齢が同じ 26 の雷禅さんと中村さん、24 の林檎さんと田中さんの順番は、決まっていません。実行するたびに入れ替わることがあります。
複数の列で並べ替える
ORDER BY には列を , で区切って複数書けます。最初の列で並べ、同じ値のものは次の列で並べます。部署IDの順に並べ、同じ部署の中では年齢の大きい順にしてみましょう。
SELECT NAME, DEPT_ID, AGE FROM EMPLOYEE ORDER BY DEPT_ID, AGE DESC;
| NAME | DEPT_ID | AGE |
|---|---|---|
| 鈴木 花子 | 1 | 29 |
| 院照 心愛 | 1 | 27 |
| 渡辺 大輔 | 2 | 42 |
| 佐藤 健太 | 2 | 31 |
| 雷禅 海皇 | 2 | 26 |
| 伊藤 さくら | 2 | 22 |
| 高橋 翔 | 3 | 35 |
| 中村 結衣 | 3 | 26 |
| 林檎 星飛 | 3 | 24 |
| 田中 美咲 | 3 | 24 |
DESC は、直前の列(ここでは AGE)にだけ効きます。DEPT_ID は昇順のままです。
同じ年齢の人の順番を決めたいときも、2つ目の列を書きます。年齢の大きい順、同じ年齢なら社員IDの小さい順にすると、結果の順番が毎回同じになります。
SELECT NAME, AGE FROM EMPLOYEE ORDER BY AGE DESC, EMP_ID;
ORDER BY に書く列は、SELECT で表示していない列(ここでは EMP_ID)でもかまいません。
【知識メモ】文字の並び順
数の列は数の大小で並びます。文字の列(NAME や ADDRESS)は、文字コードの順で並ぶため、日本語は五十音順にはなりません。5.5 の結果で、都道府県が「京都府、兵庫県、大阪府、…」という順になっているのはそのためです。日付の列は、古い日付が小さい値として並びます。
5.4 列に別名を付ける:AS
結果の列の見出しは、既定では列名(NAME、AGE)です。列名 AS 別名 と書くと、見出しを変えられます。別名のことを エイリアス ともいいます。
SELECT NAME AS 氏名, AGE AS 年齢 FROM EMPLOYEE ORDER BY EMP_ID;
| 氏名 | 年齢 |
|---|---|
| 雷禅 海皇 | 26 |
| 院照 心愛 | 27 |
| 林檎 星飛 | 24 |
| 田中 美咲 | 24 |
| 佐藤 健太 | 31 |
| 鈴木 花子 | 29 |
| 高橋 翔 | 35 |
| 伊藤 さくら | 22 |
| 渡辺 大輔 | 42 |
| 中村 結衣 | 26 |
AS は省略して NAME 氏名 と書くこともできますが、この教材では読みやすさのために AS を書きます。別名は、5.6 の計算した列や、第9章の集計した列のように、そのままでは見出しが分かりにくくなる列に付けると効果があります。
【ご注意】ORDER BY に別名は書かない
SELECT NAME AS 氏名 … ORDER BY 氏名 のように、ORDER BY に別名を書くと、Oracle では「ORA-00904: "氏名": 無効な識別子です。」というエラーになることがあります(別名を " で囲まずに書いた場合)。ORDER BY には元の列名(ORDER BY NAME)を書くようにしてください。
5.5 重複をなくす:DISTINCT
社員の住所(都道府県)にどんな値があるかを知りたいとき、SELECT ADDRESS FROM EMPLOYEE では「東京都」が3行、「大阪府」が2行、と同じ値が繰り返し表示されます。SELECT の直後に DISTINCT を付けると、同じ値の行を1つにまとめて 表示します。
SELECT DISTINCT ADDRESS FROM EMPLOYEE ORDER BY ADDRESS;
| ADDRESS |
|---|
| 京都府 |
| 兵庫県 |
| 大阪府 |
| 愛知県 |
| 東京都 |
| 神奈川県 |
10人の社員の住所は、6種類だと分かります。社員がいる部署IDを調べることもできます。
SELECT DISTINCT DEPT_ID FROM EMPLOYEE ORDER BY DEPT_ID;
| DEPT_ID |
|---|
| 1 |
| 2 |
| 3 |
部署ID 4(人事部)は、社員がいないので表示されません。それぞれの値が 何行あるか を数えたいときは、第9章の GROUP BY を使います。
5.6 列の値を使って計算する
SELECT には、列名だけでなく、列を使った 計算式 も書けます。来年の年齢(年齢 + 1)を表示してみましょう。
SELECT NAME, AGE, AGE + 1 AS NEXT_AGE FROM EMPLOYEE ORDER BY EMP_ID;
| NAME | AGE | NEXT_AGE |
|---|---|---|
| 雷禅 海皇 | 26 | 27 |
| 院照 心愛 | 27 | 28 |
| 林檎 星飛 | 24 | 25 |
| 田中 美咲 | 24 | 25 |
| 佐藤 健太 | 31 | 32 |
| 鈴木 花子 | 29 | 30 |
| 高橋 翔 | 35 | 36 |
| 伊藤 さくら | 22 | 23 |
| 渡辺 大輔 | 42 | 43 |
| 中村 結衣 | 26 | 27 |
計算に使える記号は、+(足す)、-(引く)、*(掛ける)、/(割る)です。計算した列には元の列名が無いので、AS で別名を付けないと、見出しが AGE+1 のような式のままになります。
計算は 結果の表示だけ を変えます。テーブルの中の AGE の値は変わりません。テーブルの値を変えるのは、第7章の UPDATE です。文字をつなげたり、日付を計算したりする方法は、第8章で学びます。
5.7 うまくいかないときは
| 症状 | 考えられる原因と対処 |
|---|---|
| 「ORA-00942: 表またはビューが存在しません。」 | テーブル名の打ち間違いです(EMPLOYE など)。XE_SYSTEM のワークシートで実行している場合も、dbapp のテーブルは見えないのでこのエラーになります。 |
| 「ORA-00904: "〇〇": 無効な識別子です。」 | 列名の打ち間違いか、そのテーブルに無い列を書いています(部署テーブルに NAME は無く、DEPT_NAME です)。ORDER BY に別名を書いたときにも出ます。 |
| 「ORA-00936: 式がありません。」 |
SELECT NAME, AGE, FROM のように、列名の最後に余分な , があります。 |
| 「ORA-00933: SQLコマンドが正しく終了されていません。」 | 句の順番が違います(ORDER BY は文の最後)。前の SQL の ; が無く、2つの SQL がつながって実行されたときにも出ます。 |
| 「SP2-0734: "SELEC * FR..."で開始するコマンドが不明です」のような表示 |
SELECT などのキーワードのつづりが間違っています。 |
| 結果が表ではなく、文字で表示される | F5(スクリプトの実行)で実行しています。表で見たいときは、SQL の行にカーソルを置いて Ctrl + Enter(文の実行)を押してください。 |
| 別の SQL が実行されてしまう | カーソルの位置が違います。実行したい SQL の行にカーソルを置いてください。SQL と SQL の間には空行を入れておきます。 |
ほかのエラーは、付録B「よくあるエラーと対処法」 も参考にしてください。
5.8 まとめと確認問題
まとめ
-
SELECT 列名, … FROM テーブル名;でデータを取り出す。*はすべての列 -
ORDER BY 列名で並べ替える。昇順が既定、DESCで降順。複数の列を書くと、同じ値のものを次の列で並べる。ORDER BY が無い結果の順番は決まっていない -
列名 AS 別名で結果の見出しを変える。ORDER BY には元の列名を書く -
SELECT DISTINCTで、同じ値の行を1つにまとめる -
AGE + 1のように列を使って計算できる。計算は表示だけで、テーブルの値は変わらない
この章で使った SQL は、付録C「SQL 早見表」 にまとめています。
確認問題
問1 社員テーブルから、氏名と住所だけを、社員IDの順に取り出す SQL を書いてください。
解答を見る
SELECT NAME, ADDRESS FROM EMPLOYEE ORDER BY EMP_ID;
問2 社員テーブルを、生年月日の新しい順(若い人が先)に並べて、氏名と生年月日を取り出す SQL を書いてください。
解答を見る
SELECT NAME, BIRTH_DATE FROM EMPLOYEE ORDER BY BIRTH_DATE DESC;
日付は新しいほど大きい値なので、新しい順は DESC です。
問3 SELECT NAME, AGE FROM EMPLOYEE ORDER BY AGE; を2回実行したところ、年齢が同じ 24 の林檎さんと田中さんの順番が入れ替わりました。これは異常ですか。
解答を見る
異常ではありません。ORDER BY に書いた列の値が同じ行の順番は決まっていません。順番を固定したいときは、ORDER BY AGE, EMP_ID のように2つ目の列を書きます。
問4 社員テーブルに、どんな性別の値が入っているか(重複なし)を取り出す SQL を書いてください。
解答を見る
SELECT DISTINCT GENDER FROM EMPLOYEE ORDER BY GENDER;
結果は 1 と 2 の2行です。
問5 SELECT NAME, AGE * 12 FROM EMPLOYEE; を実行すると、2つ目の列の見出しはどうなりますか。見出しを MONTHS にするにはどう書きますか。
解答を見る
見出しは式のまま AGE*12 になります。SELECT NAME, AGE * 12 AS MONTHS FROM EMPLOYEE; と別名を付けます。
