コマンド道場

SELECT 句の使い方

列を選んでも、行数は変わらない

shain社員

shain_idnamebusho_idjoushi_idsalaryhired_ontaishoku_on
1鈴木1NULL9800002014-04-01NULL
2佐藤217200002016-10-01NULL
3田中225200002019-04-01NULL
4中村225300002020-04-01NULL
5小林224450502024-04-01NULL
6加藤526100002018-04-01NULL

SELECT name, salary取り出した結果

namesalary
鈴木980000
佐藤720000
田中520000
中村530000
小林445050
加藤610000

SELECT name, salary

  • 緑の列= 結果に残す列。それ以外の列は出てきません
  • 社員 18取り出した結果 18(行数は変わりません)

「選ぶ」と聞くと行が減りそうですが、減るのは列だけです。行を減らすのは WHERE の仕事です。

SELECT何を出すかを決める場所です。書けるのは列名だけではなく、計算式でも関数でも構いません。行を絞るのは `WHERE`、行を並べるのは `ORDER BY` で、SELECT は行数に一切影響しません。ここを分けて覚えると、あとの句がすべて理解しやすくなります。

主要 7 製品で通用 そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server / Oracle Database / IBM Db2

製品ごとの対応表(実測)を見る

このページの実行結果と図は、すべて本物のデータベースに同じ SQL を流して得たものです。手で書いた「たぶんこうなる」ではありません。

01必要な列だけを並べる

結論: `SELECT` に書いた順が、そのまま結果の列の順になります。

列はカンマで区切って並べます。表にある順番と同じである必要はありません。並べ替えても、取り出す内容は変わりません。

出したい列だけを書く癖をつけてください。通信量が減り、あとで表の定義が変わっても壊れにくくなります

1 行ずつ、何をしているか
  1. SELECT name, salary何を出すか(最後に効く)
  2. FROM shainどの表を見るか(最初に効く)
  3. WHERE busho_id = 2どの行を残すか
  4. ORDER BY salary DESC並び順

書く順番と評価される順番は違います。FROM → WHERE → SELECT → ORDER BY の順に効きます。

氏名と給与だけを取り出す
SELECT name, salary FROM shain ORDER BY shain_id;
namesalary
鈴木980000
佐藤720000
田中520000
中村530000
小林445050
加藤610000

18 … うち先頭 6 行を表示

18 行のまま、列だけが 2 つになりました。行数は変わっていません。

並べる順を入れ替える
SELECT salary, name FROM shain ORDER BY shain_id;
salaryname
980000鈴木
720000佐藤
520000田中
530000中村
445050小林
610000加藤

18 … うち先頭 6 行を表示

書いた順がそのまま列の順になります。中身は同じで、見え方だけが変わります。

02⚠️ SELECT * は避ける

結論: *** は「実行時点の全列」を意味します。表の定義が変われば結果も変わります。**

手で確かめるときは便利ですが、プログラムやビューに残すと危険です。あとから列が追加されたとき、結果の列数が黙って増えます。列の位置で値を読んでいる処理は、そこで壊れます。

必要な列を明示しておけば、表に列が増えても結果は変わりません。

全列を取り出す
SELECT * FROM shain ORDER BY shain_id;
shain_idnamebusho_idjoushi_idsalaryhired_ontaishoku_on
1鈴木1NULL9800002014-04-01NULL
2佐藤217200002016-10-01NULL
3田中225200002019-04-01NULL
4中村225300002020-04-01NULL

18 … うち先頭 4 行を表示

7 列すべてが出ます。今は 7 列ですが、表に列が増えれば 8 列になります。

必要な 2 列だけを取り出す
SELECT shain_id, name FROM shain ORDER BY shain_id;
shain_idname
1鈴木
2佐藤
3田中
4中村

18 … うち先頭 4 行を表示

こちらは表に列が増えても 2 列のままです。使う側の処理が壊れません。

03計算式と別名

結論: `SELECT` には計算式も書けます。名前は `AS` で決めます。

列名は式の特別な場合にすぎません。salary * 12 のような計算も、関数呼び出しも同じように書けます。

AS を省略すると、名前は処理系が決めます。PostgreSQL では ?column? のような名前になり、プログラムから使うと壊れます。式を書いたら名前も付ける、と覚えてください。

年収を計算して名前を付ける
SELECT name, salary * 12 AS nenshu FROM shain ORDER BY shain_id;
namenenshu
鈴木11760000
佐藤8640000
田中6240000
中村6360000
小林5340600

18 … うち先頭 5 行を表示

計算結果に nenshu という名前が付きました。元の表には存在しない列です。

⚠️ AS を書かないとどうなるか
SELECT name, salary * 12 FROM shain ORDER BY shain_id;
name?column?
鈴木11760000
佐藤8640000
田中6240000

18 … うち先頭 3 行を表示

列名が ?column? になりました。この名前に依存した処理は書けません。

04⚠️ 別名を使える場所と使えない場所

結論: `ORDER BY` では別名が使えますが、`WHERE` では使えません。

理由は評価される順番です。WHERESELECT より先に評価されるため、その時点では別名という列がまだ存在しません。ORDER BYSELECTあとなので使えます。

WHERE で同じ条件を使いたいときは、式をもう一度書きます。「書く順番」ではなく「評価される順番」で決まる、という点がここの要点です。

評価される順番
  1. FROMどの表を見るか
  2. WHEREどの行を残すか
  3. SELECT何を出すか(別名が決まる)
  4. ORDER BY並び順(別名が使える)

別名が決まるのは SELECT の段階です。だからそれより前の WHERE では使えません。

ORDER BY では別名が使える
SELECT name, salary * 12 AS nenshu FROM shain ORDER BY nenshu DESC LIMIT 5;
namenenshu
鈴木11760000
佐藤8640000
山田8400000
清水7800000
加藤7320000

5

並べ替えは SELECT のあとなので、そこで付けた名前をそのまま使えます。

⚠️ この書き方は SQL Server / Oracle Database / IBM Db2 では使えません(LIMIT n)。製品ごとの対応表

⚠️ WHERE では別名が使えない
SELECT name, salary * 12 AS nenshu FROM shain WHERE nenshu > 8000000;
ERROR: column "nenshu" does not exist

WHERE の時点では nenshu という列がまだ作られていません。存在しない列として扱われます。

WHERE には式をもう一度書く
SELECT name, salary * 12 AS nenshu FROM shain WHERE salary * 12 > 8000000 ORDER BY nenshu DESC;
namenenshu
鈴木11760000
佐藤8640000
山田8400000

3

少し冗長ですが、これが標準的な書き方です。式が長いなら副問い合わせや WITH で段階を分けます。

05同じ値の行をまとめたいときは

結論: `SELECT` だけでは重複は消えません。`DISTINCT` を付けます。

SELECT busho_id FROM shain は、社員の数だけ行を返します。同じ部署の社員が何人いても、その人数ぶん行が出ます。

DISTINCTSELECT の直後に 1 回だけ書き、並べた列の組み合わせに対して効きます。列ごとに効くのではない点に注意してください。

そのまま出すと社員の数だけ行が出る
SELECT busho_id FROM shain ORDER BY busho_id NULLS LAST;
busho_id
1
2
2
2
2
3
3
3

18 … うち先頭 8 行を表示

同じ部署番号が何度も現れています。行は社員 1 人につき 1 行だからです。

⚠️ この書き方は MySQL / MariaDB / SQL Server では使えません(ORDER BY ... NULLS LAST)。製品ごとの対応表

DISTINCT で重複を消す
SELECT DISTINCT busho_id FROM shain ORDER BY busho_id NULLS LAST;
busho_id
1
2
3
4
5
7
NULL

7

実際に社員がいる部署の番号と、部署なし(NULL)が 1 行ずつになりました。

⚠️ この書き方は MySQL / MariaDB / SQL Server では使えません(ORDER BY ... NULLS LAST)。製品ごとの対応表

自分で打ってみる

このページの例と同じデータが入った本物のデータベースを、この場(あなたのブラウザの中)で起動できます。打った SQL がサーバーへ送られることはありません。

押すと初回だけ約 9MB を読み込みます(2 回目以降はキャッシュされます)。

解いてみる

読んだだけでは書けるようになりません。実行結果で採点します。

関連するトピック

  • WHERE 句行を絞るのは SELECT ではなく WHERE です。
  • ORDER BY 句並べ替えは SELECT のあとに評価されます。別名が使えるのはそのためです。
  • DISTINCT重複を消したいときに使います。列の組み合わせに効きます。

根拠(一次情報)