文字列の解析とフォーマット
方言をまたいだSUBSTRING、位置取得、分割、大小文字変換を学びます。
「文字列の解析とフォーマット」はCoddyKit上の無料SQL Interview Prepレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Interview Prep学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Interview Prepコースには全4レッスンが含まれています。
なぜ文字列関数が問われるのか
実際のデータは乱れています。分割が必要なフルネーム、取り出したいメールドメイン、IDに埋め込まれたコード、大文字と小文字が混在した値などがあります。面接官は文字列操作を通じて、スクリプトに書き出さずにテキストをクレンジングし、形を整えられるかを確認します。
日付関数と同様、文字列関数も標準化の度合いが低いため、目標は概念と一般的な方言の違いを理解することです。
- 部分文字列の抽出と位置の検索
- 連結
- 分割と置換
- 大文字・小文字の変換とトリミング
SUBSTRING と位置の検索
SUBSTRING(s FROM start FOR length) は SQL 標準の形式です。多くのエンジンでは SUBSTRING(s, start, length) も使えます。文字列の位置は1始まりです。0始まりの言語に慣れたプログラマーにとって、典型的なオフバイワンの落とし穴です。
POSITION(sub IN s)(または STRPOS/CHARINDEX)は、部分文字列の開始位置を検索します。見つからない場合は0を返します。
SELECT
SUBSTRING('INV-2024-042' FROM 5 FOR 4) AS year, -- '2024'
POSITION('-' IN 'INV-2024-042') AS first_dash; -- 4メールドメインを抽出する
定番の実践例です。@ の位置を探し、その後ろにあるすべての文字を取り出します。POSITION と SUBSTRING を組み合わせるのが、移植性の高い方法です。
PostgreSQL では SPLIT_PART(email, '@', 2) も使えます。こちらのほうが読みやすく、慣用的な答えとして言及する価値があります。
-- Portable
SELECT SUBSTRING(email FROM POSITION('@' IN email) + 1) AS domain
FROM users;
-- Postgres idiom
SELECT SPLIT_PART(email, '@', 2) AS domain FROM users;方言による連結方法の違い
文字列の連結方法は方言によって異なるため、面接官はその違いを知っていることを期待します。
- SQL 標準 / Postgres / Oracle:
||演算子 - MySQL:
CONCAT(a, b, c)(||演算子はデフォルトで論理 OR です) - SQL Server:文字列には
+、またはCONCAT()
CONCAT() は NULL を空文字列として扱います。一方、|| と + は通常、どれかのオペランドが NULL だと結果全体を NULL にします。これは見落としやすいバグの原因です。
-- Postgres
SELECT first_name || ' ' || last_name AS full_name FROM people;
-- MySQL / SQL Server
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM people;NULL 連結の落とし穴
前の場面に続く話です。last_name が NULL の場合、Postgres では first_name || ' ' || last_name は NULL になり、名前全体が失われます。
防御的な対策は、NULL になり得る部分に COALESCE を使うことです。または、区切り文字付き連結を行う CONCAT_WS を使います。これは NULL を無視し、値が存在する部分の間にだけ区切り文字を挿入します。
-- Safe in Postgres / MySQL
SELECT CONCAT_WS(' ', first_name, last_name) AS full_name FROM people;
-- Or guard each part
SELECT first_name || ' ' || COALESCE(last_name, '') FROM people;文字列を分割する
「ハイフンで区切られたコードから3番目のセグメントを取り出す」という問題では、分割の方法が試されます。PostgreSQL の SPLIT_PART(s, delim, n) は n 番目の部分を直接返すため、最も簡潔なツールです。
MySQL には直接的な分割関数がありません。そのため、SUBSTRING_INDEX を入れ子にするのが慣用的な方法です。最初に先頭から n 個の部分を取り出し、その結果から最後の部分を取り出します。
-- Postgres
SELECT SPLIT_PART('a-b-c-d', '-', 3); -- 'c'
-- MySQL: third part of a-b-c-d
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('a-b-c-d', '-', 3), '-', -1); -- 'c'置換、トリミング、パディング
面接で見ればすぐに使えることを期待されるクレンジング操作です。
REPLACE(s, from, to)は、すべての出現箇所を置き換えます。TRIM(s)は先頭と末尾の空白を削除します。TRIM(BOTH 'x' FROM s)は特定の文字を削除します。LPAD(s, len, ch)/RPADは固定幅になるよう埋めます。IDのゼロ埋めに便利です。
SELECT
REPLACE('555.123.4567', '.', '-') AS phone, -- 555-123-4567
TRIM(' hello ') AS clean, -- 'hello'
LPAD('42', 6, '0') AS padded; -- '000042'大文字・小文字の変換と長さ
テキストを比較またはグループ化する前に、大文字・小文字を統一することは不可欠です。UPPER と LOWER はほぼすべての環境で使えます。INITCAP(Postgres/Oracle)は単語の先頭を大文字にします。
LENGTH(s) は多くのエンジンで文字数を返しますが、注意が必要です。SQL Server では LEN() を使い、設定によっては LENGTH がマルチバイト文字列のバイト数を数えることがあります。ASCII以外のデータでは、この違いに触れておくとよいでしょう。
SELECT
LOWER(email) AS email_norm,
INITCAP(city) AS city_pretty, -- Postgres
LENGTH(description) AS chars
FROM places;LIKE を超えるパターンマッチング
LIKE では力不足な場合、面接官は正規表現を知っているか確認したがります。PostgreSQL には ~ 演算子と REGEXP_REPLACE / REGEXP_MATCHES があり、MySQL には REGEXP / REGEXP_SUBSTR があります。
例として、電話番号の文字列から数字だけを残す処理を考えます。正規表現を使えば、REPLACE を何度も連鎖させる代わりに1行で書けます。
-- Postgres: strip non-digits
SELECT REGEXP_REPLACE('(555) 123-4567', '[^0-9]', '', 'g')
AS digits; -- '5551234567'発展例:名前を正規化して重複排除する
複数のクレンジング処理を組み合わせる課題です。名前に余分な空白や大文字・小文字の混在があると、同じ名前が重複しているように見えてしまいます。まず正規化してから、グループ化します。
前後の空白を取り除き、正規表現で内部の空白を1つにまとめ、カウントする前に小文字へ変換します。これは、面接官が評価する典型的な複数ステップの思考です。
SELECT
LOWER(REGEXP_REPLACE(TRIM(name), '\s+', ' ', 'g')) AS norm_name,
COUNT(*) AS occurrences
FROM contacts
GROUP BY 1
ORDER BY occurrences DESC;文字列を数値や日付にキャストする
文字列型の列に、本来は数値や日付であるべき値が入っていることはよくあります。CAST(s AS INTEGER) または Postgres の短縮構文 s::int で変換できますが、不正な入力があると失敗します。
日付の場合、TO_DATE(s, 'YYYY-MM-DD')(Postgres/Oracle)は明示的なフォーマットマスクで解析します。日と月の順序が曖昧になるのを防げるため、最も安全な方法です。
SELECT
CAST(qty_text AS INTEGER) AS qty,
TO_DATE(order_str, 'DD/MM/YYYY') AS order_date
FROM staging;確認問題
文字列の連結における NULL の動作について考えてみましょう。
復習:文字列の解析とフォーマット
面接に持っていく重要なポイント:
- 文字列の位置は1始まりです。
SUBSTRING+POSITIONで位置を指定して抽出します。 ||(Postgres)、CONCAT(MySQL)、+(SQL Server)で連結します。NULL の伝播を忘れず、CONCAT_WSを優先してください。- Postgres では
SPLIT_PART、MySQL では入れ子にしたSUBSTRING_INDEXで分割します。 REPLACE、TRIM、LPAD、UPPER/LOWERでクレンジングと正規化を行い、難しいケースには正規表現を使います。- 誤った重複を避けるため、グループ化する前に大文字・小文字と空白を正規化します。
よくある質問
「文字列の解析とフォーマット」レッスンは無料ですか?
はい。「文字列の解析とフォーマット」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Interview Prepコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Interview Prepコースには全4レッスンが含まれています。
「文字列の解析とフォーマット」で何を学びますか?
方言をまたいだSUBSTRING、位置取得、分割、大小文字変換を学びます。 ブラウザで直接実行するハンズオンコードでSQL Interview Prepを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
SQL Interview Prepを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSQL Interview Prepは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「文字列の解析とフォーマット」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSQL Interview Prepレッスンでコードを書いて実行できますか?
はい。すべてのSQL Interview Prepレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 日付の計算とインターバル
- 日付の切り捨てとバケット化
- 文字列の解析とフォーマット
- タイムゾーンとタイムスタンプ