🧚 聞いてください!Beekeeper Studio は高速でモダンなオープンソースのデータベース GUI です ダウンロード
2026年5月4日 著者: Matthew Rathbone

SUBSTRING は、指定した位置から指定した文字数分だけ文字列の一部を返します。テキスト列からプレフィックスやコード、メールのドメインを取り出すときに SQL で使う方法です。例は PostgreSQL、MySQL、SQLite、SQL Server で動作します。

SUBSTRING の使い方

SUBSTRING には、文字列、開始位置(最初の文字は 1)、取り出す文字数を渡します。長さを省略すると末尾までをすべて取り出します:

SUBSTRING(string, start, length)
SELECT SUBSTRING('Joe Bloggs', 1, 3);
-- Output: Joe

-- No length: the rest of the string (SQL Server needs all three arguments)
SELECT SUBSTRING('Joe Bloggs', 5);
-- Output: Bloggs

実際のクエリでは、文字列は通常カラムです。ORD-2024-001 のような注文番号では、5〜8文字目に年が入っています:

-- Input: orders
-- order_number
-- ------------
-- ORD-2024-001
-- ORD-2025-014
-- ORD-2026-102

SELECT order_number, SUBSTRING(order_number, 5, 4) AS year
FROM orders;

-- Output:
-- order_number | year
-- -------------+-----
-- ORD-2024-001 | 2024
-- ORD-2025-014 | 2025
-- ORD-2026-102 | 2026

知っておくべきルール

  • 位置は 0 ではなく 1 から始まります。負の開始位置は文字列の末尾から数えますが、これは MySQL と SQLite のみです:
SELECT SUBSTRING('Joe Bloggs', -6, 6);
-- Output: Bloggs
-- PostgreSQL and SQL Server return '' (an empty string) instead
  • 末尾を超えてもエラーにはなりません。存在する文字だけが返され、開始位置が末尾を超えている場合は空文字列になります:
SELECT SUBSTRING('Bob', 1, 10);
-- Output: Bob

SELECT SUBSTRING('Hello', 10, 5);
-- Output: '' (an empty string)
  • NULL を渡すと NULL が返ります。値が必要な場合は COALESCE で囲みます:
SELECT SUBSTRING(NULL, 1, 5);
-- Output: NULL
-- SQL Server rejects a bare NULL here, but a NULL column gives NULL
  • プレフィックスでの絞り込みには SUBSTRING ではなく LIKE を使います。WHERE SUBSTRING(product_code, 1, 3) = 'ELE' は WHERE product_code LIKE 'ELE%' と同じ行を返しますが、product_code のインデックスを使えるのは LIKE の方だけです。

別の構文

SUBSTRING の別名である SUBSTR や、文字列の両端から文字を取り出す LEFT と RIGHT もよく見かけます:

-- Not in SQL Server
SELECT SUBSTR('Joe Bloggs', 1, 3);
-- Output: Joe

-- Not in SQLite: use SUBSTRING('Joe Bloggs', 1, 3) and SUBSTRING('Joe Bloggs', -6)
SELECT LEFT('Joe Bloggs', 3);
-- Output: Joe

SELECT RIGHT('Joe Bloggs', 6);
-- Output: Bloggs

-- PostgreSQL and MySQL: the standard SQL form
SELECT SUBSTRING('Joe Bloggs' FROM 1 FOR 3);
-- Output: Joe

特定の文字の後から始めるには、まずその位置を求めます:

SELECT INSTR('joe@example.com', '@');
-- Output: 4
-- PostgreSQL: POSITION('@' IN 'joe@example.com'); SQL Server: CHARINDEX('@', 'joe@example.com')

SUBSTRING はいつ使うべき?

必要な部分が文字列内の決まった位置、または検索できる文字の直後にある場合は SUBSTRING を使いましょう。ほとんどの用途は次の4つのいずれかに当てはまります。

先頭の数文字を取り出す

コードや名前は先頭に意味を持つことがよくあります。商品コードのカテゴリ、イニシャル、長い説明文の短いプレビューなどです。SUBSTRING(column, 1, n) で先頭の n 文字を取り出せます。

固定フォーマットの値からフィールドを取り出す

すべての値が同じレイアウトなら、各部分はどの行でも同じ位置にあります。(303) 555-0147 のような電話番号の市外局番、ORD-2024-001 の年、古いシステムの固定長レコードの各フィールドなどです。

区切り文字の後のテキストを抽出する

メールのドメイン、ファイルの拡張子、URL のパスは、行ごとに位置が変わる文字の後から始まります。INSTR でその位置を求め、1文字後から文字列の残りを取り出します。

末尾の数文字を残す

カード番号や口座番号のマスク、サフィックスの読み取りでは、末尾から数える必要があります。文字列の長さから開始位置を計算するか、MySQL と SQLite では負の開始位置を使います。

SUBSTRING の実例

コード内のカテゴリ別に商品数を数える

商品コードは3文字のカテゴリで始まります。そのプレフィックスでグループ化して、各カテゴリの商品数を数えます:

-- Input: products
-- product_code | name
-- -------------+-----------
-- ELE-1234     | USB-C Hub
-- FUR-0087     | Desk Chair
-- ELE-5521     | Webcam
-- OFF-2210     | Stapler

SELECT SUBSTRING(product_code, 1, 3) AS category, COUNT(*) AS products
FROM products
GROUP BY SUBSTRING(product_code, 1, 3)
ORDER BY category;

-- Output:
-- category | products
-- ---------+---------
-- ELE      | 2
-- FUR      | 1
-- OFF      | 1

固定長レコードを解析する

古いシステムからのエクスポートでは、区切り文字なしでフィールドが固定位置に詰め込まれていることがよくあります。ここでは名前が8文字(スペースで埋められており、TRIM で除去します)、生年月日が次の8文字、都市コードが最後の3文字です:

-- Input: legacy_data
-- record
-- -------------------
-- JOHNDOE 19850315NYC
-- MARYLEE 19780912CHI
-- JANEROE 19900722LAX

SELECT
  TRIM(SUBSTRING(record, 1, 8)) AS name,
  SUBSTRING(record, 9, 8) AS birth_date,
  SUBSTRING(record, 17, 3) AS city_code
FROM legacy_data;

-- Output:
-- name    | birth_date | city_code
-- --------+------------+----------
-- JOHNDOE | 19850315   | NYC
-- MARYLEE | 19780912   | CHI
-- JANEROE | 19900722   | LAX

各ファイルの拡張子を取得する

ドットを見つけて、その後ろをすべて取り出します。WHERE 句でドットのないファイルを除外します:

-- Input: documents
-- filename
-- ---------------
-- q3-report.pdf
-- budget.xlsx
-- README
-- team-photo.jpeg

SELECT
  filename,
  SUBSTRING(filename, INSTR(filename, '.') + 1) AS extension
FROM documents
WHERE INSTR(filename, '.') > 0;

-- Output:
-- filename        | extension
-- ----------------+----------
-- q3-report.pdf   | pdf
-- budget.xlsx     | xlsx
-- team-photo.jpeg | jpeg

PostgreSQL では INSTR の代わりに POSITION('.' IN filename) を使います。SQL Server では CHARINDEX('.', filename) を使い、LEN(filename) などの長さを指定します。

カード番号をマスクする

カード番号はすべて16桁とは限らないため、開始位置を固定すると American Express の番号が途中で切れてしまいます。代わりに末尾から数えます:

-- Input: payments
-- customer_name | card_number
-- --------------+-----------------
-- Lena Fischer  | 4111111111111111
-- Marcus Reid   | 5500005555555559
-- Aiko Tanaka   | 378282246310005

-- Wrong: position 13 only works for 16-digit cards
SELECT customer_name, '**** ' || SUBSTRING(card_number, 13, 4) AS masked_card
FROM payments;

-- Output:
-- customer_name | masked_card
-- --------------+------------
-- Lena Fischer  | **** 1111
-- Marcus Reid   | **** 5559
-- Aiko Tanaka   | **** 005

-- Right: start 4 characters from the end
SELECT customer_name, '**** ' || SUBSTRING(card_number, LENGTH(card_number) - 3, 4) AS masked_card
FROM payments;

-- Output:
-- customer_name | masked_card
-- --------------+------------
-- Lena Fischer  | **** 1111
-- Marcus Reid   | **** 5559
-- Aiko Tanaka   | **** 0005

MySQL と SQL Server では、|| の代わりに CONCAT() で文字列を連結します。SQL Server ではさらに LENGTH() の代わりに LEN() を使います。

SUBSTRING についてさらに読む

このブログの記事:

公式ドキュメント:

Beekeeper Studioは無料のオープンソースのデータベースGUIです

これまで使った中で最高のSQLクエリ&エディタツールです。データベースの管理に必要なものがすべて揃っています。 - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studioは高速で直感的、そして使いやすいツールです。多数のデータベースに対応し、Windows、Mac、Linuxで快適に動作します。

BeekeeperのLinux版は100%フル機能。手抜きも機能の妥協も一切ありません。

Beekeeper Studio 利用者の声

★★★★★
「Beekeeper Studio は以前の SQL ワークフローを完全に置き換えてくれました。高速で直感的で、データベース作業がまた楽しくなりました。」
— Alex K.、データベース開発者
★★★★★
「多くのデータベース GUI を試してきましたが、Beekeeper は機能とシンプルさのバランスが完璧です。とにかくちゃんと動きます。」
— Sarah M.、フルスタックエンジニア