> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MySQL の文字列関数

> MySQL の文字列関数のリファレンスガイド: CONCAT、SUBSTRING、TRIM、REPLACE、UPPER、LOWER、LENGTH、LIKE、REGEXP、FORMAT、およびよく使う文字列操作のパターン。

> [card] [VillageSQL is a drop-in replacement for MySQL with extensions.](https://villagesql.com/docs/en/8.4/stable/install-server.md)
>
> All examples on this page work on VillageSQL. Install Now →

MySQL の文字列関数は、テキストの分割、結合、検索、整形、および比較をカバーします。ほとんどは同じ規則に従います。1 始まりのインデックス、NULL の伝播(いずれかの引数が NULL なら NULL を返す)、およびデフォルトでの大文字小文字を区別しない比較です。

## 結合と分割

**CONCAT** — 文字列を連結します。

```sql theme={null}
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users;

-- CONCAT_WS: join with a separator, skipping NULLs
SELECT CONCAT_WS(', ', city, state, country) AS address FROM locations;
```

`CONCAT` は引数に NULL があると NULL を返します。`CONCAT_WS` は NULL 値をスキップしますが、NULL でない値の間の区切り文字は保持します。

**SUBSTRING / SUBSTR / MID** — 文字列の一部を取り出します。

```sql theme={null}
-- SUBSTRING(string, start, length)  — 1-based indexing
SELECT SUBSTRING('Hello, World!', 1, 5);   -- 'Hello'
SELECT SUBSTRING('Hello, World!', 8);      -- 'World!'  (to end of string)
SELECT SUBSTRING('Hello, World!', -6);     -- 'World!'  (from the right)
```

**SUBSTRING\_INDEX** — 区切り文字で分割します。

```sql theme={null}
-- Get everything before the second comma
SELECT SUBSTRING_INDEX('a,b,c,d', ',', 2);   -- 'a,b'

-- Get everything after the last dot (domain from email)
SELECT SUBSTRING_INDEX('user@example.com', '@', -1);  -- 'example.com'
```

## 文字列内の検索

**LOCATE / POSITION / INSTR** — 部分文字列を探します。

```sql theme={null}
SELECT LOCATE('World', 'Hello, World!');       -- 8  (1-based position)
SELECT LOCATE('world', 'Hello, World!');       -- 8  (case-insensitive by default)
SELECT LOCATE('xyz', 'Hello, World!');         -- 0  (not found)

-- LOCATE with start position
SELECT LOCATE('o', 'Hello, World!', 6);        -- 9  (skips first 'o')
```

**LIKE** — ワイルドカードによるパターン一致です。

```sql theme={null}
-- % matches zero or more characters, _ matches exactly one
SELECT * FROM products WHERE name LIKE 'Widget%';       -- starts with Widget
SELECT * FROM products WHERE name LIKE '%Pro%';         -- contains Pro
SELECT * FROM products WHERE code LIKE 'SKU-___-2024';  -- three chars in middle
```

**REGEXP / RLIKE** — 正規表現による一致です。

```sql theme={null}
SELECT * FROM users WHERE email REGEXP '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$';
SELECT * FROM products WHERE name REGEXP 'Pro|Plus|Max';
```

`REGEXP` は POSIX 正規表現の構文を使います。関数形式には `REGEXP_LIKE()`(MySQL 8.0 以降)を使ってください。

## 文字列の変更

**REPLACE** — 部分文字列のすべての出現を置き換えます。

```sql theme={null}
SELECT REPLACE('Hello, World!', 'World', 'MySQL');  -- 'Hello, MySQL!'
UPDATE articles SET content = REPLACE(content, 'old_term', 'new_term');
```

**TRIM / LTRIM / RTRIM** — 空白または特定の文字を取り除きます。

```sql theme={null}
SELECT TRIM('  hello  ');                    -- 'hello'
SELECT TRIM(LEADING '0' FROM '007');         -- '7'
SELECT TRIM(BOTH 'x' FROM 'xxhelloxx');      -- 'hello'
```

**UPPER / LOWER** — 大文字と小文字を変換します。

```sql theme={null}
SELECT UPPER('hello');   -- 'HELLO'
SELECT LOWER('HELLO');   -- 'hello'
```

**LPAD / RPAD** — 固定長までパディングします。

```sql theme={null}
SELECT LPAD('42', 6, '0');    -- '000042'
SELECT RPAD('hello', 10, '.');  -- 'hello.....'
```

**REPEAT** — 文字列を N 回繰り返します。

```sql theme={null}
SELECT REPEAT('ab', 3);   -- 'ababab'
```

**REVERSE** — 文字列を反転します。

```sql theme={null}
SELECT REVERSE('hello');  -- 'olleh'
```

## 長さと比較

MySQL には 2 つの長さ関数があり、マルチバイト文字に対して異なる結果を返します。

| 関数 | 測定するもの |
| :- | :- |
| `LENGTH(s)` | バイト長 |
| `CHAR_LENGTH(s)` / `CHARACTER_LENGTH(s)` | 文字数 |

```sql theme={null}
SELECT LENGTH('café');      -- 5  (the é is 2 bytes in UTF-8)
SELECT CHAR_LENGTH('café'); -- 4  (4 characters)
```

バイト数ではなく文字数が重要な場合は、常に `CHAR_LENGTH` を使ってください。

**STRCMP** — 2 つの文字列を比較し、-1、0、または 1 を返します。

```sql theme={null}
SELECT STRCMP('abc', 'abc');   -- 0
SELECT STRCMP('abc', 'abd');   -- -1
SELECT STRCMP('abd', 'abc');   -- 1
```

## 整形

**FORMAT** — 数値を桁区切り付きで整形します。

```sql theme={null}
SELECT FORMAT(1234567.891, 2);    -- '1,234,567.89'
SELECT FORMAT(1234567.891, 2, 'de_DE');  -- '1.234.567,89'  (German locale)
```

**LEFT / RIGHT** — 先頭または末尾から N 文字を取り出します。

```sql theme={null}
SELECT LEFT('Hello, World!', 5);   -- 'Hello'
SELECT RIGHT('Hello, World!', 6);  -- 'World!'
```

## よく使うパターン

メールアドレスからドメインを取り出します。

```sql theme={null}
SELECT SUBSTRING_INDEX(email, '@', -1) AS domain FROM users;
```

表示用に長い文字列を切り詰めます。

```sql theme={null}
SELECT CASE
    WHEN CHAR_LENGTH(description) > 100
    THEN CONCAT(LEFT(description, 97), '...')
    ELSE description
END AS short_description
FROM products;
```

空白を正規化します。

```sql theme={null}
UPDATE users SET name = TRIM(REGEXP_REPLACE(name, '\\s+', ' '));
```

## よくある質問

#### MySQL の文字列比較は大文字と小文字を区別しますか?

デフォルトでは区別しません。文字列比較は列の照合順序を使い、一般的な照合順序のほとんどは大文字と小文字を区別しません(例: `utf8mb4_general_ci`。`ci` は case-insensitive の意味です)。大文字と小文字を区別する比較には、`_cs` の照合順序または `BINARY` 演算子を使います。

```sql theme={null}
SELECT * FROM users WHERE BINARY username = 'Alice';
-- or: WHERE username COLLATE utf8mb4_bin = 'Alice'
```

#### CHAR\_LENGTH と LENGTH の違いは何ですか?

`LENGTH` はバイト数を返し、`CHAR_LENGTH` は文字数を返します。ASCII 文字列では同じです。マルチバイト文字(アクセント付き文字、絵文字、CJK)を含む UTF-8 文字列では異なります。ユーザーに見える文字列長の制限には `CHAR_LENGTH` を使ってください。

## トラブルシューティング

| 問題 | 解決策 |
| :- | :- |
| `CONCAT` が NULL を返す | 引数の 1 つが NULL です。連結する前に `COALESCE(col, '')` で NULL を置き換えるか、`CONCAT_WS` を使います |
| `LIKE '%pattern%'` が遅い | 先頭のワイルドカードがインデックスの使用を妨げます。大規模なテキスト検索には FULLTEXT インデックスを検討します |
| 文字列比較が期待した行に一致しない | 大文字小文字の区別または照合順序の不一致です。`SHOW CREATE TABLE` で列の照合順序を確認します |
| `LIKE` が一致したものに `REPLACE` が一致しなかった | `REPLACE` はバイト単位で比較し、接続の照合順序を無視するため、`_ci` の列でも大文字と小文字を*区別*します。`=`、`LIKE`、`LOCATE` とは異なります |
| `SUBSTRING` が NULL ではなく空文字列を返す | 範囲外の位置に対する SUBSTRING は、NULL ではなく空文字列を返します |

## 関連項目

* [MySQL の文字セットと照合順序](https://villagesql.com/docs/ja/guides/character-sets.md) — 文字列関数は照合順序によって動作が異なる
* [MySQL の全文検索](https://villagesql.com/docs/ja/guides/full-text-search.md) — LIKE を超えた大規模な文字列検索
* [MySQL の列エイリアス](https://villagesql.com/docs/ja/tutorial/column-aliases.md) — 文字列式が生成する列に名前を付ける
* [MySQL の LIKE](https://villagesql.com/docs/ja/tutorial/like.md) — これらの関数と一緒によく使われるパターン演算子
* [MySQL の GROUP\_CONCAT](https://villagesql.com/docs/ja/tutorial/group-concat.md) — グループ内の値を 1 つの文字列に連結する


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.