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句に AnnualRevenueIndustry は含まれていませんが、WHERE句で問題なく絞り込み条件として使えています。APIで連携する際など、不要なデータを取得せずに済むため、パフォーマンス向上にも繋がる非常に便利な仕様です。

違い② JOINがない!代わりに「リレーションクエリ」を使う

SQLでテーブルを結合する際に必須の INNER JOINLEFT JOIN。実は、SOQLにはこのJOIN句が存在しません。

その代わりに、SOQLではSalesforceのオブジェクト間に定義された「リレーションシップ(参照関係・主従関係)」を利用して、関連オブジェクトのデータを取得します。これをリレーションクエリと呼びます。リレーションクエリには大きく2つの書き方があります。

1. 子から親の項目を取得する(子-親リレーション)

子オブジェクトのクエリ内で、親オブジェクトの項目を . (ドット)で繋いで取得します。SQLのJOINに似た感覚で使えます。

SOQLの例文

取引先責任者(Contact)のリストを取得する際に、それぞれが所属する取引先(Account)の名前も一緒に取得したいケースです。

SELECT 
  LastName, 
  FirstName, 
  Account.Name -- 親である取引先の名前を取得
FROM 
  Contact 
WHERE 
  Account.Name != null

Account.NameAccount の部分は、Contactオブジェクトの「AccountId」項目のリレーション名です。このようにドット記法で親の項目に簡単にアクセスできます。

2. 親とそれに紐づく子のレコードをまとめて取得する(親-子リレーション)

親オブジェクトのクエリ内で、子のレコードをサブクエリとしてまとめて取得します。1回のクエリで親子両方のデータを階層構造で取得できるため、非常に強力です。

SOQLの例文

特定の取引先(Account)と、その取引先に紐づく**全ての取引先責任者(Contact)**の情報を一度に取得したいケースです。

SELECT 
  Name, 
  (
    SELECT 
      LastName, 
      FirstName 
    FROM 
      Contacts -- 子リレーション名(通常は子オブジェクト名の複数形)
  ) 
FROM 
  Account 
WHERE 
  Name = '株式会社NextStep'

SELECT句の中に (SELECT ...) というサブクエリが入っているのが特徴です。FROM ContactsContacts は、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つご紹介しました。

SOQLSQL
WHERE句の項目SELECT句になくてもOKSELECT句にある項目が基本
オブジェクト結合リレーションクエリ(親子関係)JOIN句INNER JOINなど)
全項目取得不可(項目を明示的に指定)SELECT *可能

SOQLは一見するとSQLに似ていますが、Salesforceのオブジェクト構造とガバナ制限に最適化された独自の言語です。特に、JOINの代わりにリレーションクエリを使いこなすことが、SOQLをマスターする鍵となります。

この記事が、あなたのSalesforce開発の一助となれば幸いです!

投稿者 てきとうSE

普段はシステムエンジニアとして、SalesforceなどのSaaS製品と日々向き合っています。

コメントを残す

名前は任意です。未入力の場合は「匿名」として投稿されます。