Q1次のうち、SELECT DISTINCT の説明として正しいものはどれですか。
DISTINCT・ORDER BY・LIMIT — 結果セットを整える
SQL の DISTINCT・ORDER BY・LIMIT・OFFSET を解説します。重複除去、並び替え、件数制限、OFFSET によるページングまで、CSV の成績データを使ってブラウザで実行しながら学べます。
本記事で使うデータ — CSV から読み込んだ score テーブル
本記事では CSV ファイルから自動ロードされた `score` テーブル を題材に、SELECT の結果を整える 4 つの構文 — DISTINCT(重複除去)、ORDER BY(並び替え)、LIMIT(件数制限)、OFFSET(先頭スキップ)— を順に学びます。
score テーブルは id / name / subject / score / recorded_on の 5 列を持ち、5 名の受験者(Alice / Bob / Carol / Dave / Eve)が Math / English / Science の 3 科目を受験した、計 15 行のデータです。
DISTINCT — 重複行を除いて取り出す
SELECT の結果に 同じ値の行が複数回 含まれることがあります。たとえば score テーブルから name 列だけを取り出すと、Alice / Bob / Carol / Dave / Eve の 5 名がそれぞれ 3 科目分、計 15 行返ります。
`SELECT DISTINCT 列, ...` の形に書くと、結果セットの中で 重複している行をまとめて 1 行に圧縮 できます。複数列を指定した場合は「列の組み合わせ」が同じ行を重複と見なします。
-- 受験者の名前を重複なく一覧で取り出す
SELECT DISTINCT name FROM score;
-- 受験した科目を重複なく一覧で取り出す
SELECT DISTINCT subject FROM score;
-- 「名前と科目」の組み合わせで重複除去(= 全 15 行が一意)
SELECT DISTINCT name, subject FROM score;
ORDER BY — 結果を並び替える
SQL は 行の順序を保証しない のが基本仕様で、SELECT * FROM score; のように書いてもどの順番で行が返るかは DB の実装に任されます。結果を意図通りの順序で並べたいときは `ORDER BY 列 [ASC|DESC]` を付けます。
- ASC(昇順 / 小 → 大)が既定値で、省略可
- DESC(降順 / 大 → 小)は明示的に書く
- カンマ区切りで 複数列 を指定すると、第 1 列が同じ行は第 2 列で並べる、という多段ソートになります
-- 1) 1 列で昇順(ASC は省略可)
SELECT name, score FROM score ORDER BY score;
-- 2) 1 列で降順
SELECT name, score FROM score ORDER BY score DESC;
-- 3) 複数列で並び替え(科目順 → 同科目内は点数の高い順)
SELECT name, subject, score FROM score ORDER BY subject ASC, score DESC;
ORDER BY の細かい仕様
- ORDER BY は WHERE のあと、LIMIT の前に置くのが正しい順序です。SELECT 列 FROM 表 WHERE 条件 ORDER BY 列 DESC LIMIT N; の並びを覚えておくと迷いません。
- ORDER BY の右辺には 列番号(ORDER BY 2 DESC で SELECT した 2 つ目の列で並べる)も書けますが、可読性が落ちるので 列名で書く のが主流です。
- 文字列の並び順は本講座のコンソールでは大文字 → 小文字の順(ASCII 順)になります。DB によっては 'A' と 'a' を同等に扱う場合もあります。
LIMIT と OFFSET — 件数を絞ってページングする
結果セットが 100 行・1 万行と大きくなると、画面に全部出すと重くなり、ユーザーも見切れません。`LIMIT N` を付けると 先頭から N 行だけ を取り出せます。これに `OFFSET M` を組み合わせると、先頭 M 行を読み飛ばしてから N 行 を取り出せるので、「6〜10 件目」「11〜20 件目」のように ページング ができます。
-- 1) 上位 5 件を取り出す(ランキング TOP 5)
SELECT name, subject, score FROM score
ORDER BY score DESC
LIMIT 5;
-- 2) 6 件目〜10 件目を取り出す(2 ページ目)
SELECT name, subject, score FROM score
ORDER BY score DESC
LIMIT 5 OFFSET 5;
-- 3) ページング式: ページ N、1 ページ K 件
-- LIMIT K OFFSET (N - 1) * K
-- 例: 3 ページ目、1 ページ 5 件 → LIMIT 5 OFFSET 10
| ページ | 1 ページの件数 | OFFSET | LIMIT | 対象順位 |
|---|---|---|---|---|
| 1 | 5 | 0 | 5 | 1〜5 位 |
| 2 | 5 | 5 | 5 | 6〜10 位 |
| 3 | 5 | 10 | 5 | 11〜15 位 |
| 1 | 10 | 0 | 10 | 1〜10 位 |
| 2 | 10 | 10 | 10 | 11〜20 位 |
| 1 | 20 | 0 | 20 | 1〜20 位 |
ORDER BY なしの LIMIT は順序が保証されない
SELECT * FROM score LIMIT 5; のように `ORDER BY` を省いて `LIMIT` だけを書くと、どの 5 行が返るかは DB の実装に任されます。SQLite のように挿入順で返ることが多い DB でも、SQL の規格上は順序は不定です。MySQL / PostgreSQL ではインデックスや実行計画の都合で別の行が返ることがあります。
ランキング・ページング・「先頭 N 件」のような順序が意味を持つ取得には、必ず `ORDER BY` を付けてから `LIMIT` を書きます。
理解度チェック
まずは1問ずつ答えてみましょう。
Q2SELECT name, score FROM score ORDER BY score DESC; の結果として正しいものはどれですか。
Q3SELECT * FROM score ORDER BY score DESC LIMIT 5 OFFSET 10; を実行したときに返る行として正しいものはどれですか。