【SQL】LENGTH関数で文字列の長さを取得する方法|CHAR_LENGTH・RDBMS別の違い・実務パターン

【SQL】LENGTH関数で文字列の長さを取得する方法|CHAR_LENGTH・RDBMS別の違い・実務パターン SQL

LENGTH関数は、SQLで文字列の長さを取得するための基本関数です。しかし、RDBMSによって「文字数」を返すのか「バイト数」を返すのかが異なるため、正しく理解していないとマルチバイト文字(日本語など)を扱う際に思わぬバグを生むことがあります。

この記事では、LENGTH関数の基本構文から、CHAR_LENGTH・OCTET_LENGTH・LEN・DATALENGTH との違いRDBMS別の挙動比較、WHERE句やORDER BY・CASEとの組み合わせなど実務で使えるパターンまで、文字列長の取得に関する全体像を解説します。

💡 この記事でわかること

  • LENGTH関数の基本構文と使い方
  • LENGTH / CHAR_LENGTH / OCTET_LENGTH / LEN / DATALENGTH の違いと使い分け
  • RDBMS別(MySQL・PostgreSQL・Oracle・SQL Server)の挙動の違い
  • マルチバイト文字(日本語)での注意点
  • WHERE / ORDER BY / CASE / GROUP BY との実務パターン
  • NULLや空文字の扱い、パフォーマンスの注意点
スポンサーリンク

LENGTH関数の基本構文

LENGTH関数は、引数に渡した文字列の「長さ」を数値で返します。

LENGTH(文字列)
-- リテラル文字列の長さを取得
SELECT LENGTH('Hello, World!');  -- 結果: 13

-- テーブルのカラム値の長さを取得
SELECT
    name,
    LENGTH(name) AS name_length
FROM employees;

⚠ 重要: LENGTH関数が返す値はRDBMSによって異なります。MySQLではバイト数、PostgreSQL・Oracleでは文字数を返します。日本語などのマルチバイト文字を扱う場合、この違いは致命的です。詳しくは次のセクションで解説します。

文字列長を取得する関数の比較

SQLには文字列の長さを取得する関数が複数あり、RDBMSごとに利用できる関数が異なります。最も重要な違いは「文字数」を返すのか「バイト数」を返すのかです。

関数一覧と返却値の違い

関数 返却値 対応RDBMS
LENGTH() MySQL: バイト数 / PostgreSQL・Oracle: 文字数 MySQL, PostgreSQL, Oracle
CHAR_LENGTH() 文字数(全RDBMSで統一) MySQL, PostgreSQL
CHARACTER_LENGTH() 文字数(CHAR_LENGTHのエイリアス) MySQL, PostgreSQL
OCTET_LENGTH() バイト数 MySQL, PostgreSQL
LENGTHB() バイト数 Oracle
LEN() 文字数(末尾スペースを除外) SQL Server
DATALENGTH() バイト数(末尾スペースを含む) SQL Server

マルチバイト文字での違いを確認

半角英数字では違いが見えませんが、日本語(マルチバイト文字)で比較すると関数の違いが明確になります。

-- MySQL(UTF-8環境)での実行結果
SELECT
    LENGTH('データベース')        AS len_result,      -- 15(バイト数: 5文字 × 3バイト)
    CHAR_LENGTH('データベース')   AS charlen_result,  -- 5(文字数)
    OCTET_LENGTH('データベース')  AS octlen_result;   -- 15(バイト数)
文字列 LENGTH
MySQL
CHAR_LENGTH
MySQL
LENGTH
PostgreSQL
LENGTH
Oracle
'Hello' 5 5 5 5
'東京' 6 2 2 2
'A1あ' 5 3 3 3
''(空文字) 0 0 0 NULL

🚨 MySQLのLENGTHはバイト数を返す: MySQLの LENGTH() はUTF-8環境で日本語1文字を3バイトとしてカウントします。MySQLで文字数が欲しい場合は必ず CHAR_LENGTH() を使いましょう。

ℹ️ Oracleは空文字をNULLとして扱う: Oracleでは空文字列 '' は NULL と同等に扱われるため、LENGTH('') は 0 ではなく NULL を返します。これは Oracle 独自の仕様です。

RDBMS別の書き方

各RDBMSで「文字数」と「バイト数」を正しく取得する方法をまとめます。

MySQL

-- 文字数を取得(推奨)
SELECT CHAR_LENGTH('データベース');  -- 結果: 5

-- バイト数を取得
SELECT LENGTH('データベース');       -- 結果: 15(UTF-8)

-- OCTET_LENGTH は LENGTH と同じ(バイト数)
SELECT OCTET_LENGTH('データベース');  -- 結果: 15

-- BIT_LENGTH はビット数を返す(バイト数 × 8)
SELECT BIT_LENGTH('データベース');   -- 結果: 120(15バイト × 8)

PostgreSQL

-- 文字数を取得
SELECT LENGTH('データベース');        -- 結果: 5
SELECT CHAR_LENGTH('データベース');   -- 結果: 5

-- バイト数を取得
SELECT OCTET_LENGTH('データベース');  -- 結果: 15(UTF-8)

Oracle

-- 文字数を取得
SELECT LENGTH('データベース') FROM DUAL;   -- 結果: 5

-- バイト数を取得
SELECT LENGTHB('データベース') FROM DUAL;  -- 結果: 15(AL32UTF8)

Oracleの文字数・バイト数取得について詳しくは「Oracleで文字列の文字数・バイト数を取得する方法」をご覧ください。

SQL Server

-- 文字数を取得(末尾スペースを除外)
SELECT LEN(N'データベース');        -- 結果: 5

-- バイト数を取得(末尾スペースを含む)
SELECT DATALENGTH(N'データベース'); -- 結果: 10(nvarchar: 1文字2バイト)

-- LEN の末尾スペース除外に注意
SELECT LEN(N'ABC   ');             -- 結果: 3(末尾スペースを除外)
SELECT DATALENGTH(N'ABC   ');    -- 結果: 12(6文字 × 2バイト、スペース含む)

ℹ️ SQL Serverの注意点: LEN() は末尾のスペースをカウントしませんが、DATALENGTH() は末尾スペースもバイト数に含めます。また、nvarchar 型は1文字2バイト、varchar 型はエンコーディング依存です。

RDBMS別まとめ: 文字数を取得するならこの関数

RDBMS 文字数を取得 バイト数を取得
MySQL CHAR_LENGTH() LENGTH() / OCTET_LENGTH()
PostgreSQL LENGTH() / CHAR_LENGTH() OCTET_LENGTH()
Oracle LENGTH() LENGTHB()
SQL Server LEN() DATALENGTH()

WHERE句で文字数を条件にデータを抽出する

LENGTH関数をWHERE句で使うと、文字数を条件にしてレコードを絞り込めます。データのバリデーションや品質チェックに頻出するパターンです。

基本: 文字数が一定以上のデータを抽出

-- 名前が10文字以上の社員を取得(MySQL)
SELECT employee_id, name
FROM employees
WHERE CHAR_LENGTH(name) >= 10;

-- PostgreSQL / Oracle の場合
SELECT employee_id, name
FROM employees
WHERE LENGTH(name) >= 10;

データ品質チェック: 異常データの検出

-- 電話番号が10桁または11桁でないレコードを検出
SELECT customer_id, phone_number
FROM customers
WHERE CHAR_LENGTH(phone_number) NOT IN (10, 11);

-- メールアドレスが短すぎるレコードを検出(x@y.z = 最短5文字)
SELECT user_id, email
FROM users
WHERE CHAR_LENGTH(email) < 5;

-- 郵便番号が7桁でないレコードを検出
SELECT address_id, postal_code
FROM addresses
WHERE CHAR_LENGTH(REPLACE(postal_code, '-', '')) <> 7;

✅ 実務ポイント: 郵便番号の例のように、REPLACE関数で不要な文字を除去してからLENGTH/CHAR_LENGTHで長さをチェックするパターンは、データクレンジングの定番テクニックです。

ORDER BY で文字数順にソートする

LENGTH関数をORDER BY句で使うと、文字列の長さ順でソートできます。

-- 商品名を文字数が少ない順にソート(MySQL)
SELECT
    product_name,
    CHAR_LENGTH(product_name) AS name_length
FROM products
ORDER BY CHAR_LENGTH(product_name) ASC;

-- 文字数が多い順にソート
SELECT
    product_name,
    CHAR_LENGTH(product_name) AS name_length
FROM products
ORDER BY CHAR_LENGTH(product_name) DESC;

文字数を基準にしたソートの詳細パターンは「文字数をカウントして多い順や少ない順でソートする方法」で詳しく解説しています。

CASE文と組み合わせて文字数で分類する

CASE文と組み合わせることで、文字数に応じてデータを分類・ラベル付けできます。

-- コメントの文字数に応じてラベルを付ける(MySQL)
SELECT
    comment_id,
    CHAR_LENGTH(comment_text) AS text_length,
    CASE
        WHEN CHAR_LENGTH(comment_text) < 50   THEN '短文'
        WHEN CHAR_LENGTH(comment_text) < 200  THEN '通常'
        WHEN CHAR_LENGTH(comment_text) < 1000 THEN '長文'
        ELSE '超長文'
    END AS length_category
FROM comments;

GROUP BY と組み合わせて文字数別に集計

-- コメントを文字数カテゴリ別に件数集計(MySQL)
SELECT
    CASE
        WHEN CHAR_LENGTH(comment_text) < 50   THEN '50文字未満'
        WHEN CHAR_LENGTH(comment_text) < 200  THEN '50〜199文字'
        WHEN CHAR_LENGTH(comment_text) < 1000 THEN '200〜999文字'
        ELSE '1000文字以上'
    END AS length_range,
    COUNT(*) AS cnt
FROM comments
GROUP BY length_range
ORDER BY MIN(CHAR_LENGTH(comment_text));

他の文字列関数との組み合わせ

LENGTH関数は単体でも便利ですが、他の文字列関数と組み合わせることでさらに強力な処理が可能です。

TRIM + LENGTH: 前後の空白を除いた文字数

-- 前後の空白を除いた実質的な文字数を取得(MySQL)
SELECT
    name,
    CHAR_LENGTH(name) AS with_spaces,
    CHAR_LENGTH(TRIM(name)) AS without_spaces
FROM employees;

TRIM関数の詳しい使い方は「TRIM関数で文字列から空白や指定した文字を取り除く方法」をご覧ください。

LENGTH – REPLACE: 特定文字の出現回数をカウント

-- カンマの数を数える = CSVフィールドの項目数を推定(MySQL)
SELECT
    csv_data,
    CHAR_LENGTH(csv_data) - CHAR_LENGTH(REPLACE(csv_data, ',', '')) AS comma_count
FROM import_data;

-- 応用: カンマが3つ以上のレコードを検出
SELECT *
FROM import_data
WHERE CHAR_LENGTH(csv_data) - CHAR_LENGTH(REPLACE(csv_data, ',', '')) >= 3;

✅ テクニック解説: LENGTH(str) - LENGTH(REPLACE(str, '検索文字', '')) は、検索文字を空文字に置換した際の文字数差分から出現回数を算出するイディオムです。REPLACE関数の詳しい使い方はこちら

SUBSTR + LENGTH: 末尾N文字を取得

-- ファイル名の拡張子(末尾4文字)を取得(Oracle)
SELECT
    file_name,
    SUBSTR(file_name, LENGTH(file_name) - 3) AS extension
FROM documents;

-- MySQL の場合: SUBSTRING + CHAR_LENGTH または RIGHT 関数
SELECT
    file_name,
    SUBSTRING(file_name, CHAR_LENGTH(file_name) - 3) AS extension,
    RIGHT(file_name, 4) AS extension2
FROM documents;

SUBSTR関数の詳しい使い方は「SUBSTR関数で文字列の一部を切り出す方法」をご覧ください。

NULLと空文字の扱い

LENGTH関数にNULLや空文字を渡したときの挙動はRDBMSによって異なります。

入力 MySQL
CHAR_LENGTH
PostgreSQL
LENGTH
Oracle
LENGTH
SQL Server
LEN
NULL NULL NULL NULL NULL
''(空文字) 0 0 NULL 0
' '(スペース1つ) 1 1 1 0
-- NULLを含むカラムの安全な文字数チェック(MySQL)
SELECT
    name,
    COALESCE(CHAR_LENGTH(name), 0) AS safe_length
FROM employees;

-- Oracle: 空文字もNULLも考慮した安全なチェック
SELECT
    name,
    NVL(LENGTH(name), 0) AS safe_length
FROM employees;

パフォーマンスの注意点

注意点 詳細 対策
インデックスが効かない WHERE句でLENGTH(col)を使うと、カラムのインデックスが使われずフルスキャンになる 頻繁に検索する場合は、文字数を格納する計算カラム(Generated Column)を追加してインデックスを張る
大量データでの遅延 数百万件以上のテーブルでWHERE LENGTH(col) を使うと処理が重くなる 他の条件で先に絞り込んでからLENGTHを適用する
文字セット依存 MySQLのLENGTH()はバイト数を返すため、文字セットが変わると結果が変わる 文字数が必要な場合は常にCHAR_LENGTH()を使用する
-- MySQL 5.7以降: Generated Column でインデックスを活用
ALTER TABLE products
ADD COLUMN name_length INT GENERATED ALWAYS AS (CHAR_LENGTH(product_name)) STORED;

CREATE INDEX idx_name_length ON products(name_length);

-- インデックスが効くようになる
SELECT * FROM products WHERE name_length >= 20;

よくあるトラブルと対処法

症状 原因 対処法
日本語の文字数が実際より多い MySQLのLENGTH()がバイト数を返している CHAR_LENGTH() に変更する
空文字のLENGTHがNULLになる Oracleの仕様(空文字=NULL) NVL(LENGTH(col), 0) で対応
末尾スペースがカウントされない SQL ServerのLEN()の仕様 DATALENGTH() を使うか、末尾にダミー文字を付けて計測
絵文字の文字数がおかしい サロゲートペア文字がDB環境で正しく処理されない MySQL: utf8mb4 を使用。Oracle: LENGTH2() を検討
LENGTH関数が見つからないエラー SQL ServerにはLENGTH()がない LEN() に変更する

関連する記事

記事 内容
文字数をカウントして多い順や少ない順でソートする方法 LENGTH/CHAR_LENGTHとORDER BYの実践パターン
Oracleで文字列の文字数・バイト数を取得する方法 LENGTH/LENGTHBの詳細とOracleでの実務パターン
SUBSTR関数で文字列の一部を切り出す方法 LENGTHと組み合わせた末尾切り出しパターン
TRIM関数で文字列から空白や指定した文字を取り除く方法 空白除去後の文字数チェックの定番パターン
REPLACE関数で指定された文字を別の文字列で置換する方法 LENGTH – REPLACEによる文字出現回数カウントの基礎
COUNT関数でレコード数をカウントする方法 集計関数の基本(GROUP BYと合わせて活用)
SQLで文字列を検索する方法 LIKE演算子やINSTR関数による文字列検索

まとめ

ポイント 内容
MySQLで文字数を取得 CHAR_LENGTH() を使う(LENGTH() はバイト数)
PostgreSQL・Oracleで文字数を取得 LENGTH() がそのまま文字数を返す
SQL Serverで文字数を取得 LEN() を使う(末尾スペース除外に注意)
バイト数を取得 MySQL: LENGTH() / PostgreSQL: OCTET_LENGTH() / Oracle: LENGTHB() / SQL Server: DATALENGTH()
NULLの扱い 全RDBMSで LENGTH(NULL) は NULL。Oracle は空文字も NULL
パフォーマンス WHERE句での使用はインデックスが効かない。Generated Columnで対策可能

LENGTH関数はシンプルに見えて、RDBMSごとの挙動の違いやマルチバイト文字の扱いなど注意点が多い関数です。特にMySQLを使う場合は「文字数が欲しいならCHAR_LENGTH()」「バイト数が欲しいならLENGTH()」と覚えておくだけで、多くのトラブルを防げます。WHERE句でのデータ品質チェックやCASE文での分類など、実務でも活用範囲が広いので、ぜひ使いこなしてください。