SQLite | ゼロからはじめるSQL、30日で習得するSQLite:検索力強化 - Day8 並び替え

SQL SQLite
スポンサーリンク

Day8 後半

並び替えを「思いどおりに操る」感覚を身につける

前半で、ORDER BYASC / DESC の基本はつかめました。
後半では、もう一歩踏み込んで、複数列での並び替え や、「あれ、順番おかしくない?」と感じたときの考え方 を扱います。

ここを越えると、「なんとなく ORDER BY を付ける」から「意図を持って並び順を設計する」に変わっていきます。


複数列で並び替えるとはどういうことか

「まずこの列で、その中でさらにこの列で」

まず、次のような users テーブルを用意します。

id | name       | age | city
---+------------+-----+---------
 1 | 山田太郎   | 25  | 東京
 2 | 佐藤花子   | 19  | 大阪
 3 | 鈴木一郎   | 30  | 東京
 4 | 高橋健     | 22  | 名古屋
 5 | 田中花子   | 30  | 大阪

ここで、次のような並び順を考えます。

「年齢の高い順に並べたい。ただし、同じ年齢の人は名前の五十音順に並べたい」

日本語で言うと、

まず age を降順(大きい→小さい)
その中で name を昇順(あ→ん)

という二段階の並び替えです。

SQL では、ORDER BY に複数の列をカンマで並べて書きます。

SELECT * FROM users
ORDER BY age DESC, name ASC;
SQL

これで、「まず age で並べ、その age が同じ行同士は name で並べる」という意味になります。

結果はこうなります。

id | name       | age | city
---+------------+-----+---------
 3 | 鈴木一郎   | 30  | 東京
 5 | 田中花子   | 30  | 大阪
 1 | 山田太郎   | 25  | 東京
 4 | 高橋健     | 22  | 名古屋
 2 | 佐藤花子   | 19  | 大阪

30歳の中で「鈴木 → 田中」と名前順になっているのがポイントです。


昇順と降順を混ぜる

「グループの順番」と「グループ内の順番」を分けて考える

もう一つ、よくあるパターンを考えます。

「city ごとにまとめて表示したい。ただし city は五十音順、その中では年齢の高い順にしたい」

日本語で分解すると、

city を昇順(あ→ん)
同じ city の中では age を降順(大きい→小さい)

となります。

SQL はこうなります。

SELECT * FROM users
ORDER BY city ASC, age DESC;
SQL

結果のイメージはこうです。

id | name       | age | city
---+------------+-----+---------
 4 | 高橋健     | 22  | 名古屋
 2 | 佐藤花子   | 19  | 大阪
 5 | 田中花子   | 30  | 大阪
 3 | 鈴木一郎   | 30  | 東京
 1 | 山田太郎   | 25  | 東京

ここで大事なのは、「ORDER BY に書いた順番が優先順位になる」ということです。
最初に書いた city が第一キー、その次の age が第二キー、というイメージです。


並び順がおかしく見えるときに疑うべきポイント

「型」「ORDER BY の列」「ASC/DESC」の3つをチェックする

「ちゃんと ORDER BY を書いたつもりなのに、なんか順番がおかしい」と感じることがあります。
そのときに真っ先に疑うべきなのは、次の3つです。

並び替えに使っている列の「型」が正しいか
ORDER BY に指定している列が、本当に並べたい列か
ASC / DESC の向きが意図と合っているか

特に多いのが、「数値を文字列として持ってしまっている」ケースです。

たとえば、価格を TEXT で持っていて、こう並べ替えたとします。

SELECT * FROM products
ORDER BY price ASC;
SQL

priceTEXT だと、「文字列としての順番」になります。
その結果、

100
1000
200
300

のような、人間から見ると「おかしい」並びになります。
これは、'100' < '1000' < '200' という文字列比較の結果です。

Day3 でやった「型を正しく選ぶ」が、ここでも効いてきます。
数値として並べたい列は、必ず INTEGER などの数値型で定義しておく必要があります。


WHERE と ORDER BY を組み合わせた「よくある実務パターン」

「条件で絞って、新しい順に」「危険そうなものから順に」

実務で本当によく出てくるのは、次のようなパターンです。

「エラーになったログだけを、新しい順に見たい」
「未完了のタスクだけを、期限が近い順に見たい」

Day7 で作った tasks テーブルを少し拡張して、due_date(期限)列があるとします。

CREATE TABLE tasks (
  id       INTEGER,
  title    TEXT,
  detail   TEXT,
  done     INTEGER,
  due_date TEXT   -- '2025-05-01' のような文字列日付とする
);
SQL

ここで、「未完了(done = 0)のタスクだけを、期限が近い順に見たい」とします。

条件:done = 0
並び順:due_date ASC

SELECT * FROM tasks
WHERE done = 0
ORDER BY due_date ASC;
SQL

このように、「WHERE で対象を絞り、ORDER BY で優先度順に並べる」というのは、運用・監視・セキュリティ対応でも頻出のパターンです。


セキュリティの視点から見る ORDER BY

「優先的に見るべきものを上に持ってくる」という設計

セキュリティの現場では、ログやアラートを「どの順番で見るか」がとても重要です。

たとえば、
「危険度の高いアラートから順に見る」
「最近発生したものから順に見る」
といった並び替えをしておかないと、本当に対応すべきものを見落とすリスクが上がります。

SQL レベルでは、
severity(危険度)を DESC
timestamp(発生時刻)を DESC

のように ORDER BY を設計しておくことで、
「上から順に見ていけば、重要なものから処理できる」状態を作れます。

Day8 の段階では、
「ORDER BY は“見やすさ”だけでなく、“どれから対応するか”という優先順位にも関わる」
という感覚だけ持っておいてくれれば十分です。


小さな練習で締める

日本語の「〜順」を見たら、頭の中で ORDER BY に変換してみる

次の日本語を見て、頭の中で SQL にしてみてください。

年齢の若い順にユーザーを表示したい。
年齢の高い順に、かつ同じ年齢なら名前の五十音順にしたい。
未完了タスクだけを、期限が近い順に表示したい。

全部、ORDER BY 列名 ASC/DESC の組み合わせで書けます。
スラスラ出てこなければ、Day8 前半・後半の例を真似しながら、何度か手で書いてみてください。


Day8 後半のまとめ

ORDER BY には複数の列を指定でき、「書いた順番が優先順位」になる。
昇順・降順を混ぜることで、「グループの順番」と「グループ内の順番」を細かく設計できる。
並び順がおかしく見えたら、「型」「ORDER BY の列」「ASC/DESC」を疑う。
WHERE で絞り、ORDER BY で優先度順に並べる、というパターンは実務・セキュリティ運用でも非常に重要。

ここまで来たあなたは、
「どの行を」「どの列を」「どんな条件で」「どんな順番で」
取り出すかを、かなり自由にコントロールできる状態になっています。
次のステップでは、LIMIT やページング、集計(COUNT, SUM など)に進んでいくと、さらに“検索力”が立体的になっていきます。

タイトルとURLをコピーしました