「データベースの名前を50音順に並べたいのに、うまくいかない……」
そんな悩みをお持ちではありませんか?
SQL(エスキューエル)で日本語の文字列をソートする際、思った通りに並ばない原因の多くは「文字コード」と「照合順序(Collation)」にあります。
この記事では、「SQLで50音順に並び替える方法」を基礎から丁寧に解説し、実践的なソートのコツや注意点まで紹介します。
なぜSQLで50音順に並ばないのか?

文字コードと照合順序の基本
SQLが50音順にならない根本原因
SQLは世界中で使われているため、標準の設定では英語やラテン語ベースの並び順になっています。
日本語の「あいうえお順」で並べるには、**適切な照合順序(Collation)**を使わなければなりません。
よくある問題の例
-- 期待しない結果の例
SELECT name FROM users ORDER BY name;
-- 結果が以下のようになってしまう
-- お客様
-- え〜る
-- い〜とん
-- あ〜ん
-- 正しい50音順では:あ〜ん、い〜とん、う〜る、え〜る、お客様
文字コードと並び順の関係
UTF-8でのバイナリ順序
デフォルトのUTF-8バイナリ順序では、文字は内部的な数値コードで並べられます。
問題となる例
- 「あ」のUTF-8コード:E38182
- 「い」のUTF-8コード:E38184
- 「か」のUTF-8コード:E3818B
この数値順では、人間が期待する50音順とは異なる結果になってしまいます。
ひらがなとカタカナの混在問題
-- 期待しない結果
-- アイウエオ
-- かきくけこ
-- あいうえお
-- 期待する結果(50音順)
-- あいうえお
-- アイウエオ
-- かきくけこ
日本語固有の課題
濁点・半濁点の扱い
- 「か」「が」「ぱ」の順序
- 「つ」「っ」の小文字扱い
- 長音符「ー」の位置
漢字の読み方問題
- 同じ漢字でも読み方が複数ある
- データベースには読み方情報がない
- フリガナ列の必要性
つまり、50音順に並べるには「日本語に対応した照合順序」を指定する必要があるのです。
次の章では、実際に使えるSQLの構文を紹介します。
データベース別の50音順ソート方法

MySQL での実装
MySQL 8.0以降での推奨設定
-- 基本的な50音順ソート
SELECT name
FROM users
ORDER BY name COLLATE utf8mb4_ja_0900_as_cs;
照合順序の詳細説明
照合順序 | 説明 | 50音順対応 |
---|---|---|
utf8mb4_ja_0900_as_cs | MySQL 8.0の日本語対応 | ★★★ |
utf8mb4_unicode_ci | Unicode標準(大文字小文字区別なし) | ★★☆ |
utf8mb4_bin | バイナリ比較 | ★☆☆ |
より詳細なソート例
-- 複数条件でのソート
SELECT
customer_id,
customer_name,
furigana
FROM customers
ORDER BY
customer_name COLLATE utf8mb4_ja_0900_as_cs,
customer_id;
-- フリガナを優先したソート
SELECT
customer_id,
customer_name,
furigana
FROM customers
ORDER BY
furigana COLLATE utf8mb4_ja_0900_as_cs,
customer_name COLLATE utf8mb4_ja_0900_as_cs;
MySQL 5.7以前での対応
-- 古いバージョンでの代替案
SELECT name
FROM users
ORDER BY name COLLATE utf8_unicode_ci;
-- より確実な方法(フリガナ列を使用)
SELECT name, furigana
FROM users
ORDER BY furigana COLLATE utf8_unicode_ci;
PostgreSQL での実装
基本的な日本語ソート
-- PostgreSQLでの日本語ソート
SELECT name
FROM users
ORDER BY name COLLATE "ja_JP.UTF-8";
-- より詳細な設定
SELECT name
FROM users
ORDER BY name COLLATE "C"; -- バイナリ順序
-- ICU照合順序を使用(PostgreSQL 10以降)
SELECT name
FROM users
ORDER BY name COLLATE "ja-JP-x-icu";
PostgreSQLでの照合順序確認
-- 利用可能な照合順序の確認
SELECT collname
FROM pg_collation
WHERE collname LIKE '%ja%' OR collname LIKE '%JP%';
-- データベースのデフォルト照合順序確認
SELECT datcollate
FROM pg_database
WHERE datname = current_database();
SQL Server での実装
基本的な日本語ソート
-- SQL Serverでの日本語ソート
SELECT name
FROM users
ORDER BY name COLLATE Japanese_CI_AS;
-- 大文字小文字・アクセント区別の設定
SELECT name
FROM users
ORDER BY name COLLATE Japanese_CS_AS; -- Case Sensitive
SQL Serverの照合順序オプション
オプション | 意味 | 推奨度 |
---|---|---|
Japanese_CI_AS | 大文字小文字区別なし | ★★★ |
Japanese_CS_AS | 大文字小文字区別あり | ★★☆ |
Japanese_BIN | バイナリ順序 | ★☆☆ |
Oracle での実装
基本的な日本語ソート
-- Oracleでの日本語ソート
SELECT name
FROM users
ORDER BY NLSSORT(name, 'NLS_SORT=JAPANESE_M');
-- より詳細な設定
SELECT name
FROM users
ORDER BY NLSSORT(name, 'NLS_SORT=JAPANESE_M NLS_COMP=LINGUISTIC');
実践的なソート技法

フリガナ列を活用した確実な50音順
テーブル設計での工夫
-- フリガナ列を含むテーブル設計
CREATE TABLE customers (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
name_kana VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) CHARSET=utf8mb4 COLLATE=utf8mb4_ja_0900_as_cs;
-- フリガナでの確実なソート
SELECT id, name, name_kana
FROM customers
ORDER BY name_kana;
フリガナの正規化
-- フリガナの統一(全角カタカナに変換)
UPDATE customers
SET name_kana = CONVERT(name_kana USING utf8mb4)
WHERE name_kana REGEXP '[ぁ-ん]';
-- 長音記号の統一
UPDATE customers
SET name_kana = REPLACE(name_kana, 'ー', 'ー');
複雑な並び順の実現
姓名別ソート
-- 姓→名の順でソート
SELECT
SUBSTRING_INDEX(name, ' ', 1) AS family_name,
SUBSTRING_INDEX(name, ' ', -1) AS given_name,
name
FROM customers
ORDER BY
SUBSTRING_INDEX(name_kana, ' ', 1) COLLATE utf8mb4_ja_0900_as_cs,
SUBSTRING_INDEX(name_kana, ' ', -1) COLLATE utf8mb4_ja_0900_as_cs;
会社名の特殊ソート
-- 会社名の前株・後株を考慮したソート
SELECT
company_name,
CASE
WHEN company_name LIKE '株式会社%' THEN SUBSTRING(company_name, 5)
WHEN company_name LIKE '%株式会社' THEN SUBSTRING(company_name, 1, CHAR_LENGTH(company_name) - 4)
ELSE company_name
END AS sort_key
FROM companies
ORDER BY sort_key COLLATE utf8mb4_ja_0900_as_cs;
文字種混在データの処理
ひらがな・カタカナ・漢字混在の対応
-- 読み方順での統一ソート
SELECT
name,
name_kana,
CASE
WHEN name_kana IS NOT NULL AND name_kana != '' THEN name_kana
ELSE name
END AS sort_key
FROM users
ORDER BY sort_key COLLATE utf8mb4_ja_0900_as_cs;
数字を含む文字列の自然順ソート
-- 自然順ソート(商品1, 商品2, 商品10の順)
SELECT product_name
FROM products
ORDER BY
REGEXP_REPLACE(product_name, '[0-9]+', ''),
CAST(REGEXP_SUBSTR(product_name, '[0-9]+') AS UNSIGNED),
product_name COLLATE utf8mb4_ja_0900_as_cs;
パフォーマンスと設計への影響

インデックスと照合順序
インデックス効率への影響
-- 効率的なインデックス設計
CREATE INDEX idx_customer_name_kana
ON customers (name_kana)
USING BTREE;
-- 照合順序を考慮したインデックス
CREATE INDEX idx_customer_name_collate
ON customers (name COLLATE utf8mb4_ja_0900_as_cs);
パフォーマンス比較
-- 効率的な検索(インデックス使用)
SELECT * FROM customers
WHERE name_kana LIKE 'アイ%'
ORDER BY name_kana;
-- 非効率な検索(インデックス未使用)
SELECT * FROM customers
WHERE name COLLATE utf8mb4_ja_0900_as_cs LIKE 'アイ%'
ORDER BY name COLLATE utf8mb4_ja_0900_as_cs;
テーブル設計時の考慮事項
推奨テーブル設計
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL COMMENT '氏名',
name_kana VARCHAR(100) NOT NULL COMMENT 'フリガナ(全角カタカナ)',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_name_kana (name_kana),
INDEX idx_name (name)
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_ja_0900_as_cs
COMMENT='ユーザー情報テーブル';
データ整合性の確保
-- フリガナの形式チェック
ALTER TABLE users
ADD CONSTRAINT chk_name_kana_format
CHECK (name_kana REGEXP '^[ァ-ヶー・ ]+$');
-- 必須項目の設定
ALTER TABLE users
MODIFY name_kana VARCHAR(100) NOT NULL;
大量データでのパフォーマンス最適化
分割ソートの実装
-- ページネーション対応のソート
SELECT id, name, name_kana
FROM customers
WHERE name_kana >= '#{前ページの最後のフリガナ}'
ORDER BY name_kana
LIMIT 20;
キャッシュテーブルの活用
-- ソート用キャッシュテーブル
CREATE TABLE customer_sort_cache (
customer_id INT PRIMARY KEY,
sort_key VARCHAR(200),
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_sort_key (sort_key)
) ENGINE=InnoDB;
-- キャッシュを使用した高速ソート
SELECT c.id, c.name, c.name_kana
FROM customers c
JOIN customer_sort_cache csc ON c.id = csc.customer_id
ORDER BY csc.sort_key
LIMIT 100;
トラブルシューティング
よくある問題と解決法
問題1:照合順序が効かない
-- 問題の確認
SHOW TABLE STATUS LIKE 'users';
SHOW FULL COLUMNS FROM users;
-- 解決方法:テーブル・カラムの照合順序変更
ALTER TABLE users
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_ja_0900_as_cs;
ALTER TABLE users
MODIFY name VARCHAR(100)
COLLATE utf8mb4_ja_0900_as_cs;
問題2:文字化けが発生する
-- 文字コード確認
SHOW VARIABLES LIKE 'character%';
SHOW VARIABLES LIKE 'collation%';
-- 文字コード設定の修正
SET NAMES utf8mb4 COLLATE utf8mb4_ja_0900_as_cs;
問題3:期待した順序にならない
-- データの状態確認
SELECT
name,
name_kana,
HEX(name) as name_hex,
HEX(name_kana) as kana_hex
FROM users
ORDER BY name_kana
LIMIT 10;
-- 不正なデータの検出
SELECT * FROM users
WHERE name_kana REGEXP '[^ァ-ヶー・ ]';
データクレンジング
フリガナデータの正規化
-- 半角カタカナを全角に変換
UPDATE users
SET name_kana = REPLACE(
REPLACE(
REPLACE(name_kana, 'ア', 'ア'),
'イ', 'イ'
),
'ウ', 'ウ'
)
WHERE name_kana REGEXP '[ヲ-゚]';
-- 全角英数字を半角に変換
UPDATE users
SET name_kana = REPLACE(
REPLACE(name_kana, '1', '1'),
'2', '2'
)
WHERE name_kana REGEXP '[1-9A-Za-z]';
データ品質チェック
-- フリガナと氏名の整合性チェック
SELECT
name,
name_kana,
CASE
WHEN name_kana = '' THEN 'フリガナ未入力'
WHEN name_kana REGEXP '[^ァ-ヶー・ ]' THEN '不正文字含有'
WHEN CHAR_LENGTH(name_kana) > CHAR_LENGTH(name) * 3 THEN 'フリガナ長すぎ'
ELSE 'OK'
END AS status
FROM users
WHERE name_kana = ''
OR name_kana REGEXP '[^ァ-ヶー・ ]'
OR CHAR_LENGTH(name_kana) > CHAR_LENGTH(name) * 3;
応用テクニック

動的ソート条件
ユーザー指定によるソート切り替え
-- ソート条件の動的変更
SET @sort_type = 'kana'; -- 'kana' or 'name' or 'date'
SELECT id, name, name_kana, created_at
FROM customers
ORDER BY
CASE WHEN @sort_type = 'kana' THEN name_kana END,
CASE WHEN @sort_type = 'name' THEN name END,
CASE WHEN @sort_type = 'date' THEN created_at END;
多言語対応
日英混在データの処理
-- 日本語・英語混在のソート
SELECT
name,
CASE
WHEN name REGEXP '[ひらがなカタカナ漢字]' THEN 1
ELSE 2
END as sort_group
FROM users
ORDER BY
sort_group,
CASE
WHEN name REGEXP '[ひらがなカタカナ漢字]'
THEN name COLLATE utf8mb4_ja_0900_as_cs
ELSE name COLLATE utf8mb4_unicode_ci
END;
検索機能との連携
あいまい検索と50音順の組み合わせ
-- 部分一致検索結果の50音順ソート
SELECT id, name, name_kana
FROM customers
WHERE name_kana LIKE CONCAT('%', #{検索文字}, '%')
OR name LIKE CONCAT('%', #{検索文字}, '%')
ORDER BY
CASE
WHEN name_kana LIKE CONCAT(#{検索文字}, '%') THEN 1
WHEN name LIKE CONCAT(#{検索文字}, '%') THEN 2
ELSE 3
END,
name_kana COLLATE utf8mb4_ja_0900_as_cs;
まとめ
SQLで50音順に並べ替えるためには、単純なORDER BYだけでは不十分です。照合順序(Collation)を正しく指定し、使用する文字コードと整合性を取ることで、期待通りの並びを実現できます。
重要なポイントのおさらい
基本設定
COLLATE
句で日本語対応の照合順序を指定utf8mb4_ja_0900_as_cs
はMySQL8以降のおすすめ設定- データベース別に適切な照合順序を選択
設計上の考慮点
- フリガナ列の活用で確実な50音順を実現
- テーブル作成時からの照合順序設定
- インデックス設計でのパフォーマンス配慮
実運用での注意点
- データクレンジングによる品質確保
- 文字種混在データへの対応
- 大量データでのパフォーマンス最適化
データベース別推奨設定まとめ
データベース | 推奨照合順序 | 備考 |
---|---|---|
MySQL 8.0+ | utf8mb4_ja_0900_as_cs | 最も日本語に適している |
MySQL 5.7- | utf8mb4_unicode_ci + フリガナ列 | フリガナ活用が確実 |
PostgreSQL | ja_JP.UTF-8 または ja-JP-x-icu | ICU照合順序が推奨 |
SQL Server | Japanese_CI_AS | 日本語環境では標準的 |
Oracle | JAPANESE_M | NLSSORT関数と組み合わせ |
コメント