SOQLの基礎

SOQLの基礎

概要

本記事では、SOQLの基礎的な事項を実行のサンプルコードをベースにして整理しております。
まずSOQLとは、Salesforce Object Query Languageの略であり、データベース(オブジェクト)から必要となるデータを取得する際に利用するものとなります。
一般的なSQLとの違いは、いくつかありますが一つはSQLでは複数のテーブルを自由に条件指定することで結合してデータを抽出することができますが、SOQLではオブジェクト同士にリレーションがある場合にのみ結合することができます。また、SQLの’UPDATE’や’DELETE’のようなDMLはSOQLでは使用できないので、Apexで実行する必要があります。

Apexの中でSOQLを実行する2つの方法(静的SOQL、動的SOQL)から紹介します。

静的SOQL(インラインSOQL)

Apexでは[ ]句によって、静的なSOQLを記載することができます。
[ ]句の中では、 下記のようにバインド変数を使用することで条件を指定できます。

String searchfor = 'SalesforceKid' ;
Contact[] Contacts = [SELECT xyz__c, Firstname, Lastname FROM Contact WHERE Lastname = :searchfor]; 

動的SOQL

Apexの処理の中で実行するSOQLを動的に編集することができます。
実行するSOQL文をStringでDatabase.queryに渡すことができます。
SOQLの中で一つのレコードの取得に限定しているのであれば、sObjectで受けることができます。

sObject s = Database.query(string_limit_1);

複数件以上のレコードを取得するのであれば、sObjectのリストで受けます。

List<sObject> sObjList = Database.query(string);

サンプルは下記の通りとなります。

String myTestString = 'TestName';
List<sObject> sobjList = Database.query('SELECT Id FROM MyCustomObject__c WHERE Name = :myTestString');

また、バインド変数を使用しない例では下記のようにSOQL文を組み立てることもできます。

String myTestString = 'TestName';
List<sObject> sobjList = Database.query('SELECT Id FROM MyCustomObject__c WHERE Name = \'' + myTestString + '\'');

SOQLの構文(演算子)

SOQLで使用することができる各構文(演算子)を記載していきます。

=(等号)

List<Transaction__c> tns = [SELECT Name, Type__c FROM Transaction__c WHERE Mode__c = 'cash'];

>,<,>=,<=(不等号)

List<Customer__c> customer = [SELECT Id, Customer_Name__c FROM Customer__c where balace__c > 10000];

INCLUDES/EXCLUDES

複数選択リストでの条件を指定する際に使用します。
下記の例では、PassportおよびAadhar Card、もしくはPAN Cardのレコードを抽出する条件となります。

List<Customer__c> customer = [SELECT Id, Customer_Name__c, Balance__c FROM Customer__c  WHERE Proof__c INCLUDES ('Passport;Aadhar Card', 'PAN Card')];

LIKE

SQLで使用するのと同じように部分一致の検索を行う際に使用します。
% と _ がワイルドカードしてサポートされています。
%は、0文字もしくは複数の文字列を表します。
_は、1文字を表します。

List<Account> account = [SELECT AccountId, Firstname, Lastname FROM Account WHERE Lastname LIKE 'app1_%'];

IN

SQLで使用するのと同じように複数の項目をOR条件で一致する値を指定する際に使用します。

List<Account> account = [SELECT Name FROM Account WHERE BillingState IN ('Californa', 'Newyork')];

NOT IN

SQLで使用するのと同じように複数の項目をOR条件で一致しない値を指定する際に使用します。

List<Account> account = [SELECT Name FROM Account WHERE BillingState NOT IN ('California','NewYork')];

SUBQUERY

IN句/NOT IN句には、リレーションがある子オブジェクト、または親オブジェクト条件で指定することができます。

子オブジェクトを条件に指定

List<Account> account = [SELECT Id FROM Account WHERE Id NOT IN (SELECT AccountId FROM Opportunity WHERE IsClosed = false)];

親オブジェクトを条件に指定

List<Opportunity> opportunity = [SELECT Id FROM Opportunity WHERE AccountId NOT IN (SELECT AccountId FROM Contact WHERE LeadSource = 'web')];

LIMIT

取得するレコードの上限を指定できます。

List<Account> account = [SELECT Name FROM Account WHERE Industry = 'Media' LIMIT 125];

OFFSET

取得するレコードの開始行を指定することができます。

List<Marchandise__c> marchandise = [SELECT Name FROM Marchandise__c WHERE price__c > 5.0 ORDER BY Name LIMIT 100 OFFSET 10];

GROUP BY

ある項目で集計することでCOUNT/SUM/MAX/MIN関数を使用することが集計単位ごとの値を算出できます。

List<Lead> lead = [SELECT LeadSource,Count(Name) FROM Lead GROUP BY LeadSource];

GROUP BY ROLLUP

GROUP BYにの機能に加えて、実行結果に小計行を出力されることができます。

List<Lead> lead = [SELECT LeadSource, COUNT(Name) cnt FROM Lead GROUP BY ROLLUP(LeadSource)];

[実行結果イメージ]

List<Lead> lead = [SELECT Status , LeadSource, COUNT(Name) cnt FROM Lead GROUP BY ROLLUP (Status, LeadSource)];

[実行結果イメージ]

HAVING

GROUP BYで集計した結果に対して、取得するレコードの条件を付与します。

List<Lead> lead = [SELECT LeadSource, COUNT(Name) FROM Lead GROUP BY LeadSource HAVING COUNT(Name) > 100];

リレーションを使用した値の取得、および条件指定

子から親へのアクセス

子オブジェクトから親オブジェクトをSOQLで使用したい場合は、対象の子オブジェクトで定義されている主従関係もしくは参照関係の項目により辿って親オブジェクトの所定の項目を指定できます。

List<Contact> contact = [SELECT FirstName, Account.Name From Contact];WHERE句の条件で指定することもできます。List<Contact> contact = [SELECT Id, Name, Account.Name FROM Contact WHERE Account.Industry='Media'];

カスタムオブジェクトの場合には、項目のAPI参照名の__cの部分を__rに変換して記載することになります。

List<child__c> ch = [SELECT Id, Name, parent__r.FirstName, parent__r.LastName__c from child__c WHERE age__c < 25];

親から子へのアクセス

親オブジェクトから子オブジェクトをSOQLで使用したい場合は、対象の子オブジェクトで定義されている主従関係もしくは参照関係の項目の子リレーション名により辿って子オブジェクトの所定の項目を指定できます。
contactsが子リレーション名になります。

List<Account> account = [SELECT Name,(SELECT FirstName, LastName FROM contacts) FROM Account];

カスタムオブジェクトの場合には、子リレーション名に__rを付与して記載することになります。

List<Opportunity> Parent__c = [SELECT ParentName__c, Age__c, (SELECT Child_Name__c, Dob__c FROM Child__r) FROM Parent__c];

参考

動的SOQL
https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_dynamic_soql.htm
複数選択リストのクエリ
https://developer.salesforce.com/docs/atlas.ja-jp.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_querying_multiselect_picklists.htm