「データベース」タグアーカイブ

正規表現(REGEXP)でSQLがもっと楽になる!実践パターン集

SQLの検索でよく使われる LIKE 句は便利ですが、複雑な条件指定には限界があります。
そこで強力な武器となるのが 正規表現(REGEXP)
この記事では、基本的な使い方からよく使うパターン、さらに「SQLで利用できる正規表現の一覧」をまとめました。


1. REGEXPの基本構文

SQLでは REGEXP を用いて文字列検索を行います。

➡ 名前が Aで始まるユーザー を抽出。

2. 使用できる正規表現の一覧(MySQL準拠)

SQLで使える代表的な正規表現を整理しました。
※DBエンジンにより若干差異あり(MySQL、PostgreSQL、Oracleなど)

パターン意味使用例
^行頭にマッチ^A → Aで始まる
$行末にマッチZ$ → Zで終わる
.任意の1文字c.t → cat, cot, cut
[...]文字クラス[0-9] → 数字1文字
[^...]否定の文字クラス[^0-9] → 数字以外
*0回以上の繰り返しa* → \\" a aaa"
+1回以上の繰り返しa+ → a, aa
?0回または1回colou?r → color, colour
{n}n回の繰り返し[0-9]{4} → 4桁の数字
{n,}n回以上の繰り返し[0-9]{2,} → 2桁以上の数字
{n,m}n〜m回の繰り返し[A-Z]{2,5} → 2〜5文字の大文字
|OR条件cat|dog → cat または dog
()グループ化(abc)+ → abc, abcabc
[:digit:]数字[[:digit:]] → 0〜9
[:alpha:]英字[[:alpha:]] → A〜Z, a〜z
[:alnum:]英数字[[:alnum:]] → 英数字
[:space:]空白文字[[:space:]] → 空白, 改行, タブ
[:upper:]大文字[[:upper:]] → 大文字
[:lower:]小文字[[:lower:]] → 小文字

3. よく使う実践パターン

(1) 先頭・末尾の一致

➡ Pで始まる商品コード。

(2) 日付フォーマット判定

➡ “YYYY-MM-DD” を含むログ。

(3) メールアドレス判定

➡ GmailまたはYahooメール利用者を抽出。

(4) 商品コードの書式検証

アルファベット3文字+数字 の形式に一致。

(5) 拡張子フィルタ

➡ PDFファイルだけを抽出。

4. REGEXPのメリットと注意点

メリット

  • 複雑な条件をシンプルに表現できる

  • SQLの可読性が向上

  • データ品質チェックに有効

注意点

  • DBごとに正規表現エンジンが異なる(MySQL、PostgreSQL、Oracleで互換性に注意)

  • パフォーマンス低下の可能性があるため、大量データ処理時はインデックス設計と併用が望ましい


SQLでのREGEXPサポート比較(DBMSごと)

DBMSREGEXPサポート演算子/関数例備考
MySQLREGEXP, REGEXP_REPLACE8.0以降はICUベース
PostgreSQL~, ~*, !~, !~*高度な正規表現OK
OracleREGEXP_LIKE, REGEXP_SUBSTRPOSIX互換
SQL Server(CLR関数経由)ネイティブ未対応
SQLiteREGEXP(要自作関数)デフォルト非対応
BigQueryREGEXP_CONTAINS などクラウドSQL
SnowflakeRLIKE, REGEXPほぼMySQL互換

 

まとめ

REGEXPを使えばSQLの検索が格段に柔軟になります。
一覧表を参考に、ログ解析やメール判定、コード検証などに応用してみてください。

「LIKEでは表現できない…」と思ったら、REGEXPの出番です!

SQL:サブクエリの使い方を徹底解説!実例で学ぶネストされたSELECT文

はじめに

SQLを学んでいると「サブクエリ(副問い合わせ)」という言葉を耳にすることが多いでしょう。
サブクエリは、SELECT文の中にさらにSELECT文をネスト(入れ子構造)して使う機能です。
複雑な条件指定や集計処理をシンプルに書けるため、業務システムやデータ分析で頻繁に活用されます。

この記事では、サブクエリの基本から実践的な使い方まで、実例を交えて徹底解説します。


サブクエリとは?

**サブクエリ(Subquery)**とは、SQL文の中に埋め込まれるSELECT文のことです。
通常のSQL文の一部として利用され、主に次のような用途があります。

  • WHERE句での条件指定

  • FROM句での仮想テーブル生成

  • SELECT句での派生列計算


サブクエリの基本構文

サブクエリの基本的な形は以下の通りです。

SELECT 列名 FROM テーブル WHERE 条件式 (SELECT 列名 FROM 別テーブル WHERE 条件);
ポイントは、サブクエリの結果が単一値・リスト・テーブルとして返ることです。

用途によって、スカラサブクエリ、行サブクエリ、テーブルサブクエリと呼ばれることもあります。


例1:WHERE句でのサブクエリ

もっともよく使われるのが WHERE句での利用 です。
例えば「平均給与より高い社員を取得する」場合は次のように書けます。

  • サブクエリ (SELECT AVG(給与) FROM 社員) で平均給与を取得

  • メインクエリで給与がそれを上回る社員を抽出


例2:IN句とサブクエリ

複数の値を条件にする場合は IN句 を利用します。

  • サブクエリで特定の日に注文された商品IDを取得

  • メインクエリでその商品情報を表示


例3:FROM句でのサブクエリ(派生テーブル)

FROM句でサブクエリを使えば、仮想テーブルを作成して結合や集計が可能です。

  • サブクエリで部署ごとの平均給与を計算

  • メインクエリで平均給与が30万円を超える部署を抽出


例4:SELECT句でのサブクエリ

SELECT句にサブクエリを埋め込むことで、計算列を動的に追加できます。

 
SELECT 社員名, (SELECT 部署名 FROM 部署 WHERE 部署.部署ID = 社員.部署ID) AS 部署名 FROM 社員;
  • 社員ごとに部署名をサブクエリで取得

  • JOINを使わずにシンプルに表記可能(ただしパフォーマンス注意)


サブクエリを使うときの注意点

  1. パフォーマンスに注意
    ネストが深すぎると処理速度が落ちる場合があります。JOINやCTE(共通テーブル式)で置き換えを検討しましょう。

  2. 返却される値の型に注意
    単一値を期待しているのに複数行が返るとエラーになります。

  3. 読みやすさを意識
    サブクエリは便利ですが、複雑になると可読性が低下します。適切にインデントを整えるのが重要です。

  4. DBMS別:サブクエリ対応表
    DBMSWHERE句でのサブクエリFROM句でのサブクエリSELECT句でのサブクエリ相関サブクエリ備考
    Oracle○ 完全対応○ インラインビュー○ 利用可○ 高性能大規模業務で多用
    MySQL○ (v4.1以降対応)○ 利用可○ 利用可△ パフォーマンス注意古いバージョンでは非対応
    PostgreSQL○ 標準準拠○ 利用可○ 利用可○ 高性能複雑な分析処理に強い
    SQL Server○ 完全対応○ 利用可○ 利用可○ ただし過剰利用注意実行計画が膨らむことあり

まとめ

  • サブクエリはSQL文の中でネストされたSELECT文

  • WHERE、FROM、SELECTなど多くの場面で利用可能

  • 集計や複雑な条件指定をシンプルに書ける

  • パフォーマンスと可読性に注意が必要

サブクエリをマスターすることで、SQLの表現力が大幅に広がります。
まずはシンプルなWHERE句から練習し、徐々に複雑なケースに挑戦してみましょう!

Oracle:COALESCE関数の使い方

oracleの独自関数のCOALESCE(コアレス)関数の用途についてメモしておきます。

COALESCE関数とは

COALESCE関数は引数のリストから最初のNULL以外の値を返却するOracle独自関数となります。

NVL2関数との違いは必ずしも引数へ指定するデータ型を全て合わせる必要はないことです。

ただデータの一貫性を保ちたい場合は極力データ型は合わせた方が望ましいです。

サンプルテーブル

  • サンプルテーブル「CLIENT_ADDRESS」

COALESCE関数の使用例

  • SQL(クエリー)例

    上記例ではSTART_DATEがNULLであればEND_DATEの値を、END_DATEもNULLであればsysdateを返却します。

  • 実行結果

Oracle:NVL関数とNVL2関数の違い

oracleの独自関数としてNVL関数やNVL2関数があります。

知ってると結構便利な関数なので、この2つの関数の違いについて整理しておきます。

NVL関数とは

NVL関数は第1引数がNULLなら第2引数の値(代替値)を返します。

もし第1引数の結果がNULLでなければ、そのまま第1引数の値を返します。

注意点として第1引数と第2引数へは同じデータ型を指定する必要があります。

NVL関数の使用例

  • サンプルテーブル「CLIENT_ADDRESS」
  • SQL(クエリー)例
    以下の例ではEND_DATEがNULLでない場合はEND_DATEの値を、NULLの場合はsysdateを返却します。
  • 実行結果

NVL2関数とは

NVL2関数は第1引数がNULLの場合に、第2引数の値を返却し、第1引数がNULLの場合は第3引数の値を返却します。

注意点として第1引数、第2引数、第3引数に指定する値は全て同じデータ型を指定する必要があります。

NVL2関数の使用例

  • サンプルテーブル「CLIENT_ADDRESS」
  • SQL(クエリー)例
    以下の例ではEND_DATEがNULLでない場合は第2引数のSTART_DATEの値を返却し、END_DATEがNULLの場合は第3引数のsysdateを返却します。
  • 実行結果

補足:実務での利用上の注意と代替案のご提案

Oracle の NVLNVL2 関数は便利な反面、以下のような点に留意して使うとより安全・効率的です。

  1. データ型制約に注意する
    NVL/NVL2 では、引数に与える値が「同じデータ型」でなければなりません(Oracle の仕様)という制約があります。
    たとえば、日付型と文字列型を混在させて使おうとすると、意図しない型変換やエラーを招く可能性があります。

  2. NULL の扱いが複雑な場合には COALESCE の利用も検討する
    複数の候補値を順番に評価して最初に NULL でないものを返すような処理をしたい場合は、NVL/NVL2 よりも COALESCE のほうが可読性・拡張性の面で優れるケースがあります。
    たとえば、複数の列を順番にチェックして最初の非 NULL 値を採りたいときなどには COALESCE のほうが直感的に記述できます。

  3. パフォーマンス面の配慮
    NULL チェック・代替値の置き換えという処理自体は軽い操作ですが、複雑な SQL や大規模データセットで組み合わされると、意図せぬオーバーヘッドになることがあります。
    特にインデックス条件や結合条件の中で使う場合は、実行プランを確認して予期せぬフルスキャンなどになっていないか注意しましょう。

  4. 意図の可視化
    関数を多用するクエリは読みづらくなりがちです。
    「なぜこの列で NULL チェックをするのか」「代替値にはなぜこの値を選んだか」といった背景を、コメントやドキュメントとして残しておくと、後から見直すときに助けになります。

INSERT文を指定回数分ループして実行する方法

性能試験などであるテーブルに大量データの作成が必要になった場合にINSERT文をループで処理できれば便利!という事で、SQLとロジックを組み合わせたストアドプロシージャでのサンプルプログラムとなります。

ストアドプロシージャ

上記の例では、loop_limitに指定した件数分「GOODS」テーブルへレコードを追加するサンプルコードです。

上記の例では、loop_limitを10としていますが、必要に応じて任意の数値に変更できます。

DBeaverで上記のストアドプロシージャを実行する場合は「SQLスクリプトを実行する」を選択することで正常に実行されます。

実行結果

 

Oracle:事前構成済の表領域

Oracle データベースを新規に作成すると、何も設定していなくても
いくつかの 「事前構成済の表領域」 が自動的に作られます。

これらは Oracle 本体の管理情報や、一時的な処理用領域、
一般ユーザーが使うためのデフォルト領域など、
データベース運用の土台になる重要な領域 です。

この記事では、Oracle が作成時に自動で用意してくれる主な表領域と、
それぞれがどのような役割を持っているのかを整理して解説します。


表領域とは何か?

まず前提として、表領域(tablespace) のイメージを簡単におさらいしておきます。

  • データベース内の 論理的な「入れ物」

  • 実体は 1 つ以上の データファイル(*.dbf など)

  • テーブルやインデックスなどのセグメントは、どこかの表領域に属して保存される

つまり、表領域は

「どの種類のデータを、どの物理ファイル群に格納するか」

を切り分けるための単位、と考えると分かりやすいです。


事前構成済の表領域

Oracle データベースを作成すると、デフォルトで次のような表領域が自動作成されます。

 

表領域説明
SYSTEMOracleサーバーがデータベースを管理するために使用する表領域
SYSAUXSYSTEM表領域の補助表領域
TEMPデータベースのデフォルトの一時表領域
UNDOTBS1UNDO表領域
USERS永続表領域
SYSやSYSTEMユーザー以外のユーザー用のデフォルト表領域
EXAMPLEデータベース作成時に「サンプル・スキーマの作成」を指定すると作成される表領域
 


各表領域の役割をもう少し詳しく

上の表だけだと、ニュアンスがつかみにくい部分もあるので、
代表的な表領域について、もう少し踏み込んで解説します。

SYSTEM 表領域

  • Oracle データベースの 中枢となる管理情報 が格納される領域

  • データディクショナリ(オブジェクト定義情報など)が含まれる

  • 原則として、アプリケーションのユーザーデータを入れるべきではない

SYSTEM をいっぱいにしてしまうと、
データベース全体がまともに動作しなくなる 危険があるため、
運用設計時点で「SYSTEM には触らない」というルールを決めておくことが多いです。


SYSAUX 表領域

  • SYSTEM 表領域の 補助表領域

  • さまざまなコンポーネント(Enterprise Manager など)の管理情報が格納される

  • Oracle 10g 以降で導入された、比較的新しい位置づけの表領域

SYSAUX は SYSTEM の負荷分散のために存在しているので、
こちらもアプリケーション用のオブジェクトを作成する場所ではありません。


TEMP 表領域

  • ORDER BY、GROUP BY、ソート、ハッシュ結合などの際に使われる
    一時的な作業領域

  • メモリに収まらなかったデータの「一時退避先」になる

TEMP が足りないと、次のような影響が出ます。

  • 大量データを扱う SQL の性能劣化

  • 場合によってはエラー(ORA-01652 など)で処理失敗

大量データ処理を行うシステムでは、
TEMP のサイズと使用状況を定期的に監視する運用 がほぼ必須です。


UNDOTBS1(UNDO 表領域)

  • 更新系処理の ロールバック情報(UNDO) を保存する表領域

  • トランザクションの取り消しや、一貫性のある参照(CONSISTENT READ)で利用される

UNDO が足りなくなると、

  • ロングトランザクションで古い UNDO が上書きされてしまう

  • 一貫性の保証ができなくなり、エラーが発生する

といった問題に繋がります。

特にバッチ処理など、長時間走る大量更新 があるシステムでは、
UNDO 表領域のサイズ設計が重要です。


USERS 表領域

  • 一般ユーザーがオブジェクトを作成するための デフォルト表領域

  • SYS / SYSTEM 以外のユーザーに割り当てられることが多い

小規模環境や検証用データベースでは、
「とりあえず USERS に全部作る」という運用もよくありますが、
本番環境では業務ごとに表領域を分割したり、
表とインデックスで表領域を分けるなどの設計を行う場合もあります。


EXAMPLE 表領域

  • データベース作成時に「サンプル・スキーマを作成する」を選んだ場合のみ作成される

  • サンプルスキーマ(HR, OE など)のオブジェクトが格納される

学習・検証用途には便利ですが、
本番環境では不要なことが多く、
作成しない or 不要であれば削除する といった扱いにするケースが一般的です。


実運用で意識しておきたいポイント

事前構成済の表領域は、
「最初からあるからそのまま使う」だけだと、
後から運用で困ることもあります。

実務では、特に次の点を意識しておくとトラブルを避けやすくなります。

1. SYSTEM/SYSAUX にユーザーデータを入れない

  • 管理系の表領域に業務テーブルを作らない

  • 開発時点で デフォルト表領域を USERS などに変更 しておく

2. TEMP と UNDO のサイズを定期的に確認する

  • 大量データを扱うバッチ処理の前後で使用量をチェック

  • 苦しくなってきたら、表領域の追加・拡張 を検討

3. USERS を「なんでも置き場」にしない

  • システムが大きくなる前に、業務単位で表領域を分ける設計を検討

  • バックアップ/リストア単位としても表領域分割は有効


まとめ

Oracle データベースを作成すると、
SYSTEM / SYSAUX / TEMP / UNDOTBS1 / USERS / EXAMPLE などの
事前構成済の表領域 が自動的に作成されます。

これらはそれぞれ、

  • データベース管理情報の領域

  • 各種コンポーネントの補助領域

  • ソートや一時処理用の領域

  • ロールバック情報(UNDO)用の領域

  • 一般ユーザー用のデフォルト領域

  • サンプルスキーマ用の領域

といった役割を持っており、
闇雲に使ってよい領域と、そうでない領域がはっきり分かれている のがポイントです。

開発や運用の現場では、

  • SYSTEM / SYSAUX にアプリのテーブルを作らない

  • TEMP / UNDO の使用状況を監視する

  • USERS を一時しのぎではなく、きちんと設計する

といった点を意識しておくと、
後からの障害対応やパフォーマンス劣化に悩まされにくくなります。

Oracle:データベースの起動段階と状態について

Oracleデータベースを起動すると内部的に以下の段階でデータベースが使用可能な状態となります。

データベースの起動段階と状態

 

段階ステータス状態
1SHUTDOWNデータベースが停止している状態
2NOMOUNTインスタンスが起動している状態
※制御ファイル、データファイル、REDOログファイルはクローズ
3MOUNTインスタンスが起動し、制御ファイルがオープンしている状態
※データファイル、REDOログファイルはクローズ
4OPENインスタンスが起動し、制御ファイル、データファイル、REDOログ・ファイルもオープンしている状態
※一般ユーザーが使用可能な状態
 

Oracle:制約の種類

Oracleデータベースでは以下の制約を設定することが出来ます。

Oracle DB:制約の種類

制約説明
NOT NULL制約NULL値の設定を許可しない
UNIQE制約
(一意キー制約)
一意の値のみ許可します。複数レコード登録時、重複する値を許可しません。NULL値は許可します。
CHECK制約指定した条件の値のみ許可します。
PRIMARY KEY制約
(主キー制約)
一意の値のみ許可し、重複する値は許可しません。NULL値も許可しません。
FOREIGN KEY制約
(外部キー制約)
指定した親テーブルに存在する値のみ許可します。
 

制約のポイント

  • 制約はCREATE TABLE または ALTER TABLEで設定出来ます。
  • 制約設定の構文には列制約構文と表制約構文の2種類あります。
  • NOT NULL制約は列制約構文でのみ設定出来ます。

制約の設定例

  • 下記例のNOT NULL制約の設定箇所が列制約構文、UNIQUE制約の設定箇所が表制約構文となります。

 

SQL:特定の日付時点で有効な住所情報を取得する方法

顧客の有効住所などを管理しているテーブルからある特定の日付時点で有効な住所を取得する方法をメモしておきます。

特定の日付時点で有効な住所情報を取得するサンプル

サンプルテーブル

  • 「CLIENT_ADDRESS」テーブル
    以下の様に顧客ID(CLIENT_ID)毎に有効な住所を管理するテーブルです。最新の住所のEND_DATEはnullとして管理してます。

クエリー(SQL)

  • ‘2022-03-31’時点で有効な住所情報を取得する例です。

実行結果

Oracle:プロセス構造の仕組み

Oracle DBのプロセス構造は大きく「ユーザープロセス」、「サーバープロセス」、「バックグラウンドプロセス」があります。

ユーザープロセス

  • クライアントからSQLを発行すると発生するプロセスです。

サーバープロセス

  • クライアントが発行したSQLを処理するするのがメインのプロセスです。

バックグラウンドプロセス

  • サーバープロセスがSQL管理に専念させるため、他のプロセスを監視するためのプロセスです。Oracleインスタンスを起動することで自動で起動します。
  • 主なバッググランドプロセスの種類
    種類説明
    DBWn
    (データベースライター)
    データベースバッファキャッシュ内の変更されたデータをデータファイルへ書き込む
    LGWR
    (ログライター)
    REDOログバッファにあるREDOログをREDOログファイルへ書き込む
    CKPT
    (チェックポイント)
    チェックポイント情報を制御ファイルとデータファイルヘッダーへ書き込む
    SMON
    (システムモニター)
    インスタンスのリカバリを実行する
    PMON
    (プロセスモニター)
    ユーザープロセス障害からリカバリを実施する
    ARCn
    (アーカイバー)
    REDOログファイルのコピー(アーカーブファイル)を作成する
    REDO
    (リカバラ)
    分散トランザクションに関する障害を自動的に解決する。
    MMON
    (マネージメントモニター)
    メモリー内の統計情報をスナップショットとして定期的にデーターベースへ格納する。
    MMAN
    (メモリーマネージャ)
    メモリーを必要な場所に動的に割り当てる