
Salesforceでの開発に欠かせないデータベース言語「SOQL」。SQL(Structured Query Language)に慣れている方なら、「Salesforce Object Query Language」という名前から、だいたい同じように書けるだろう、と思いがちですよね。
しかし、SOQLはSQLと似て非なるもの。SQLの感覚で書いていると「あれ、動かない…」「こんな書き方ができるの?」と驚くことが多々あります。
そこで今回は、SQL経験者が特に戸惑いやすいSOQLとSQLの構文上の大きな違いを3つ、具体的な例文付きで分かりやすく解説します!
違い① SELECT句にない項目をWHERE句で使える
これはSQL経験者が最初に「おっ!」と思うポイントかもしれません。
一般的なSQLでは、WHERE
句で条件を指定する項目はSELECT
句にも含めるのが普通です。しかしSOQLでは、オブジェクトに存在する項目であれば、SELECT
句で指定していなくてもWHERE
句の条件として自由に利用できます。
この仕様のおかげで、取得したいデータ(SELECT
句)と、絞り込みたい条件(WHERE
句)を完全に分けて考えることができ、クエリをシンプルに保てます。
SOQLの例文
例えば、取引先(Account)オブジェクトから「年間売上が1億円以上」かつ「業種がテクノロジー」の企業の名前と電話番号だけが欲しいとします。
SELECT
Name,
Phone
FROM
Account
WHERE
AnnualRevenue >= 100000000 AND Industry = 'Technology'
このクエリでは、SELECT
句に AnnualRevenue
や Industry
は含まれていませんが、WHERE
句で問題なく絞り込み条件として使えています。APIで連携する際など、不要なデータを取得せずに済むため、パフォーマンス向上にも繋がる非常に便利な仕様です。
違い② JOINがない!代わりに「リレーションクエリ」を使う
SQLでテーブルを結合する際に必須の INNER JOIN
や LEFT JOIN
。実は、SOQLにはこのJOIN句が存在しません。
その代わりに、SOQLではSalesforceのオブジェクト間に定義された「リレーションシップ(参照関係・主従関係)」を利用して、関連オブジェクトのデータを取得します。これをリレーションクエリと呼びます。リレーションクエリには大きく2つの書き方があります。
1. 子から親の項目を取得する(子-親リレーション)
子オブジェクトのクエリ内で、親オブジェクトの項目を .
(ドット)で繋いで取得します。SQLのJOINに似た感覚で使えます。
SOQLの例文
取引先責任者(Contact)のリストを取得する際に、それぞれが所属する取引先(Account)の名前も一緒に取得したいケースです。
SELECT
LastName,
FirstName,
Account.Name -- 親である取引先の名前を取得
FROM
Contact
WHERE
Account.Name != null
Account.Name
の Account
の部分は、Contactオブジェクトの「AccountId」項目のリレーション名です。このようにドット記法で親の項目に簡単にアクセスできます。
2. 親とそれに紐づく子のレコードをまとめて取得する(親-子リレーション)
親オブジェクトのクエリ内で、子のレコードをサブクエリとしてまとめて取得します。1回のクエリで親子両方のデータを階層構造で取得できるため、非常に強力です。
SOQLの例文
特定の取引先(Account)と、その取引先に紐づく**全ての取引先責任者(Contact)**の情報を一度に取得したいケースです。
SELECT
Name,
(
SELECT
LastName,
FirstName
FROM
Contacts -- 子リレーション名(通常は子オブジェクト名の複数形)
)
FROM
Account
WHERE
Name = '株式会社NextStep'
SELECT
句の中に (SELECT ...)
というサブクエリが入っているのが特徴です。FROM Contacts
の Contacts
は、Accountから見たContactの子リレーション名です。このクエリを実行すると、取引先の情報と、その内部に取引先責任者のリストがネストされた形でデータが返ってきます。
違い③ SELECT * が使えない
SQLでとりあえず全カラムのデータを見たいときによく使う SELECT *
。残念ながら、SOQLでは SELECT *
を使うことはできません。
これは、Salesforceがマルチテナント環境であり、無駄なデータ取得によるパフォーマンス低下を防ぐための仕様です。
- パフォーマンスの維持: 不必要な項目まで大量に取得すると、システムの負荷が高まり、ガバナ制限(Salesforceの利用制限)に抵触するリスクが高まります。
- API効率の最適化: 必要なデータ項目だけを明示的に指定することが、Salesforce開発のベストプラクティスとされています。
したがって、SOQLを書く際は、必ず取得したい項目を一つひとつ列挙する必要があります。
SOQLの例文
取引先の全項目を取得したいと思っても、以下のような書き方はできません。
SQL
-- これはエラーになります!
SELECT * FROM Account
必ず、以下のように必要な項目を明記します。
SOQL
-- 取得したい項目をすべて記述する必要がある
SELECT
Id,
Name,
Phone,
Industry,
AnnualRevenue
FROM
Account
まとめ
今回は、SOQLとSQLの主な違いを3つご紹介しました。
SOQL | SQL | |
WHERE句の項目 | SELECT 句になくてもOK | SELECT 句にある項目が基本 |
オブジェクト結合 | リレーションクエリ(親子関係) | JOIN句(INNER JOIN など) |
全項目取得 | 不可(項目を明示的に指定) | SELECT * が可能 |
SOQLは一見するとSQLに似ていますが、Salesforceのオブジェクト構造とガバナ制限に最適化された独自の言語です。特に、JOINの代わりにリレーションクエリを使いこなすことが、SOQLをマスターする鍵となります。
この記事が、あなたのSalesforce開発の一助となれば幸いです!