SELECT 句の使い方
shain社員
| shain_id | name | busho_id | joushi_id | salary | hired_on | taishoku_on |
|---|---|---|---|---|---|---|
| 1 | 鈴木 | 1 | NULL | 980000 | 2014-04-01 | NULL |
| 2 | 佐藤 | 2 | 1 | 720000 | 2016-10-01 | NULL |
| 3 | 田中 | 2 | 2 | 520000 | 2019-04-01 | NULL |
| 4 | 中村 | 2 | 2 | 530000 | 2020-04-01 | NULL |
| 5 | 小林 | 2 | 2 | 445050 | 2024-04-01 | NULL |
| 6 | 加藤 | 5 | 2 | 610000 | 2018-04-01 | NULL |
| … | ||||||
SELECT name, salary取り出した結果
| name | salary |
|---|---|
| 鈴木 | 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` に書いた順が、そのまま結果の列の順になります。
列はカンマで区切って並べます。表にある順番と同じである必要はありません。並べ替えても、取り出す内容は変わりません。
出したい列だけを書く癖をつけてください。通信量が減り、あとで表の定義が変わっても壊れにくくなります。
SELECT name, salary何を出すか(最後に効く)FROM shainどの表を見るか(最初に効く)WHERE busho_id = 2どの行を残すかORDER BY salary DESC並び順
書く順番と評価される順番は違います。FROM → WHERE → SELECT → ORDER BY の順に効きます。
SELECT name, salary FROM shain ORDER BY shain_id;| name | salary |
|---|---|
| 鈴木 | 980000 |
| 佐藤 | 720000 |
| 田中 | 520000 |
| 中村 | 530000 |
| 小林 | 445050 |
| 加藤 | 610000 |
(18 行 … うち先頭 6 行を表示)
18 行のまま、列だけが 2 つになりました。行数は変わっていません。
SELECT salary, name FROM shain ORDER BY shain_id;| salary | name |
|---|---|
| 980000 | 鈴木 |
| 720000 | 佐藤 |
| 520000 | 田中 |
| 530000 | 中村 |
| 445050 | 小林 |
| 610000 | 加藤 |
(18 行 … うち先頭 6 行を表示)
書いた順がそのまま列の順になります。中身は同じで、見え方だけが変わります。
02⚠️ SELECT * は避ける
結論: *** は「実行時点の全列」を意味します。表の定義が変われば結果も変わります。**
手で確かめるときは便利ですが、プログラムやビューに残すと危険です。あとから列が追加されたとき、結果の列数が黙って増えます。列の位置で値を読んでいる処理は、そこで壊れます。
必要な列を明示しておけば、表に列が増えても結果は変わりません。
SELECT * FROM shain ORDER BY shain_id;| shain_id | name | busho_id | joushi_id | salary | hired_on | taishoku_on |
|---|---|---|---|---|---|---|
| 1 | 鈴木 | 1 | NULL | 980000 | 2014-04-01 | NULL |
| 2 | 佐藤 | 2 | 1 | 720000 | 2016-10-01 | NULL |
| 3 | 田中 | 2 | 2 | 520000 | 2019-04-01 | NULL |
| 4 | 中村 | 2 | 2 | 530000 | 2020-04-01 | NULL |
(18 行 … うち先頭 4 行を表示)
7 列すべてが出ます。今は 7 列ですが、表に列が増えれば 8 列になります。
SELECT shain_id, name FROM shain ORDER BY shain_id;| shain_id | name |
|---|---|
| 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;| name | nenshu |
|---|---|
| 鈴木 | 11760000 |
| 佐藤 | 8640000 |
| 田中 | 6240000 |
| 中村 | 6360000 |
| 小林 | 5340600 |
(18 行 … うち先頭 5 行を表示)
計算結果に nenshu という名前が付きました。元の表には存在しない列です。
SELECT name, salary * 12 FROM shain ORDER BY shain_id;| name | ?column? |
|---|---|
| 鈴木 | 11760000 |
| 佐藤 | 8640000 |
| 田中 | 6240000 |
(18 行 … うち先頭 3 行を表示)
列名が ?column? になりました。この名前に依存した処理は書けません。
04⚠️ 別名を使える場所と使えない場所
結論: `ORDER BY` では別名が使えますが、`WHERE` では使えません。
理由は評価される順番です。WHERE は SELECT より先に評価されるため、その時点では別名という列がまだ存在しません。ORDER BY は SELECT のあとなので使えます。
WHERE で同じ条件を使いたいときは、式をもう一度書きます。「書く順番」ではなく「評価される順番」で決まる、という点がここの要点です。
- FROMどの表を見るか→
- WHEREどの行を残すか→
- SELECT何を出すか(別名が決まる)→
- ORDER BY並び順(別名が使える)
別名が決まるのは SELECT の段階です。だからそれより前の WHERE では使えません。
SELECT name, salary * 12 AS nenshu FROM shain ORDER BY nenshu DESC LIMIT 5;| name | nenshu |
|---|---|
| 鈴木 | 11760000 |
| 佐藤 | 8640000 |
| 山田 | 8400000 |
| 清水 | 7800000 |
| 加藤 | 7320000 |
(5 行)
並べ替えは SELECT のあとなので、そこで付けた名前をそのまま使えます。
⚠️ この書き方は SQL Server / Oracle Database / IBM Db2 では使えません(LIMIT n)。製品ごとの対応表
SELECT name, salary * 12 AS nenshu FROM shain WHERE nenshu > 8000000;WHERE の時点では nenshu という列がまだ作られていません。存在しない列として扱われます。
SELECT name, salary * 12 AS nenshu FROM shain WHERE salary * 12 > 8000000 ORDER BY nenshu DESC;| name | nenshu |
|---|---|
| 鈴木 | 11760000 |
| 佐藤 | 8640000 |
| 山田 | 8400000 |
(3 行)
少し冗長ですが、これが標準的な書き方です。式が長いなら副問い合わせや WITH で段階を分けます。
05同じ値の行をまとめたいときは
結論: `SELECT` だけでは重複は消えません。`DISTINCT` を付けます。
SELECT busho_id FROM shain は、社員の数だけ行を返します。同じ部署の社員が何人いても、その人数ぶん行が出ます。
DISTINCT は SELECT の直後に 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)。製品ごとの対応表
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重複を消したいときに使います。列の組み合わせに効きます。
根拠(一次情報)
- PostgreSQL 18 マニュアル: SELECT一次情報・確認 2026-08-02
- PostgreSQL 18 マニュアル: 選択リスト一次情報・確認 2026-08-02