最初は、ただのデータ取得ツールだと思っていました。 複雑な計算やロジックはプログラム側で処理するもの、SQLはそれを支える裏方にすぎない——そんな認識が、ある瞬間を境に一変したのです。実際に、複雑なクエリやロジックをSQLだけで表現する場面に直面したとき、「これは単なる抽出ではない」「考え方次第で、処理の設計そのものを変えられる」と気づきました。
SQLは、ロジックのカプセル化やタスクの自動化を通じて、データに“振る舞い”を持たせることができる言語です。まだ一部しか触れていないとはいえ、その可能性の広がりに、今ではすっかり魅了されています。このブログでは、私が実際に使ってみて「これは便利だ」と感じたSQLの機能を紹介します。技術に詳しくない方でも、読み進めるうちに、きっとSQLへの見方が変わるはずです。
この記事の目次
SQL機能
1. View
Viewは、SQL SELECTクエリ(クエリA)に基づく仮想テーブルです。Viewにはデータは保存されず、クエリロジックのみが保存されます。Viewに対して別のクエリ(クエリB)を実行すると、データベースは実際にはまずクエリAを実行し、その結果をクエリBが処理するための一時テーブルとして使用します。SQLツールやスキーマブラウザではViewが実際のテーブルのように見える場合がありますが、データベースには物理的には存在しません。
長所 | 短所 |
---|---|
|
|
例) CREATE VIEW active_users AS SELECT * FROM users WHERE is_active = 1; 次に、SELECT * FROM active_users; のように使用します。
2. Trigger
Triggerは、INSERT、UPDATE、DELETE など、データの変更に応じて自動的に実行されるロジックです。
あるケースでは、テーブル A に新しい行を挿入すると、テーブル B の関連する列を更新する必要がありました。Triggerを使用して、テーブル A が挿入または更新されるたびにテーブル B を自動的に更新しました。コードで手動で更新することを覚えておく必要はありません。
長所 | 短所 |
---|---|
|
|
例) CREATE TRIGGER log_delete AFTER DELETE ON users FOR EACH ROW INSERT INTO user_deletions (user_id, deleted_at) VALUES (OLD.id, NOW());
3. Stored Procedure
Stored Procedureは、パラメーターを指定して呼び出し、操作を実行したり結果を返したりできる定義済みの SQL ブロックです。
これは、コード内の findById() のようなカスタム関数のようなものですが、SQLで直接記述されています。主な違いは、ロジックを自分で定義することです。
長所 | 短所 |
---|---|
|
|
例) CREATE PROCEDURE deactivate_user(IN user_id INT) BEGIN UPDATE users SET is_active = 0 WHERE id = user_id; END; これを次のように呼びます。CALL deactivate_user(101)
4. Function
Functionとは、値を返す再利用可能なSQLブロックであり、クエリ内で使用できます。一般的には計算や書式設定に使用されます。Functionが同じ入力に対して常に同じ結果を返す場合は、DETERMINISTIC として宣言する必要があります。これは、生成された列や一部の最適化で使用するために必要です。
ユーザー テーブルに誕生日の列のみが格納されているが、クエリでユーザーの年齢を返すようにしたい場合は、誕生日に基づいて年齢を計算して返す関数を作成できます。
長所 | 短所 |
---|---|
|
|
例) CREATE FUNCTION add_vat(price DECIMAL(10,2)) RETURNS DECIMAL(10,2) DETERMINISTIC RETURN price * 1.1; → Uクエリで使用。 SELECT name, add_vat(price) FROM products;
5. Generated Column
Generated Columnは、同じ行の他の列に基づいて値が自動的に計算される列。この列は、ニーズに応じて仮想列にすることも、データベースに実際に物理的に保存することもできます。
長所 | 短所 |
---|---|
|
|
例) CREATE TABLE order_items ( unit_price DECIMAL(10,2), quantity INT, total_price DECIMAL(10,2) GENERATED ALWAYS AS (unit_price * quantity) STORED INDEX idx_total_price (total_price) );
6. Common Table Expression
Common Table Expressionは、WITH を使用して定義された一時的な名前付き結果セットです。複雑なクエリを簡素化したり、再帰を有効にしたりするために使用されます。サブクエリより読みやすく、構造を分かりやすく保てます。
長所 | 短所 |
---|---|
|
|
例) WITH high_value_orders AS ( SELECT * FROM orders WHERE total > 1000 ) SELECT customer_id, COUNT(*) FROM high_value_orders GROUP BY customer_id; → 複雑なクエリを読み取り可能な段階に分割します。
7. Window Function
現在の行に関連する行を折りたたむことなく、それらの行にわたって計算を実行する SQL 機能 (GROUP BY とは異なります)。部門内での順位付けなどに便利です。
長所 | 短所 |
---|---|
|
|
例) SELECT employee_id, department, salary, RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank FROM employees; → 従業員を給与順にランク付けする各部門内グループ化したり詳細を失ったりすることなく。
結論
SQLは単なるデータ抽出言語にとどまらず、処理の共通化・再利用・自動化まで担えるロジック層を構築できます。今回ご紹介した機能はその一部ですが、活用の幅を大きく広げてくれるはずです。すべてを使いこなす必要はありません。重要なのは、「こんなこともできる」と知っておくこと。そして、必要なときに最適な手段を選べるようになることです。
これをきっかけに、SQLを少しずつ触ってみようと思ってもらえたら嬉しいです。
この情報は役に立ちましたか?
カテゴリー:
- #ブログ