SOQL入門 SOQLにおけるJoinの方法
SOQLはJOINが出来ない…そう思っていた時期が僕にもありました。
例えば「あの取引先に紐づく取引先責任者を全部削除したい」とかそういう話はままあると思います。普通のSQLであれば「あの取引先」のIdが’hogehoge’だったとして
SELECT c.Id From Account INNER JOIN Contact ON a.Id = c.AccountId Where a.Id = ‘hogehoge’
なんてするんでしょう。SOQLではテーブルの結合が出来ず、JOINなんてもんは出来ません。
ただjoinが出来ないと参照関係のオブジェクトを持って来たい場合、一回クエリ引いてそのIdを変数に入れて…とかいう七面倒なことをしなければなりません。Query Editorも使えないし、面倒すぎる!…なんて思ってた時期がありました。
SOQLにおけるJOINは子と親で記法が違う
普通のSQLではほぼ意識しない部分になりますが、親リレーションと子リレーションでクエリの引き方が違います。
共通しているのは常にベースオブジェクト(クエリを引く起点になるオブジェクト)は一つということです。そして、クエリの結果はベースオブジェクトの1レコードにつき1行が返ってきます。
親リレーションの引き方
Contactから紐づくAccountを検索したい場合で考えます。まずは普通にContactを引くと
SELECT Id From Account
って感じですが、From句の後に引きたいリレーション名を記述します。ContactとAccountはContactIdで紐付いていますが、このリレーションにはAccountというリレーション名がついています。つまり
SELECT a.Id, c.Id FROM Contact c, Contact.Account a
という指定をすると、全てのContactとそれに紐づくAccountのIdが返ってきます。ちなみに5段階までリレーションは辿れる様です。ちなみにカスタムフィールドにおける親リレーション名は”フィールド名”+”__r”となります。”__c”でないことに注意です。
子リレーションの引き方
子リレーションを辿る場合、SELECT句にサブクエリを付ける必要があります。こちらでも上記と同様に子リレーション名を指定する必要があり、サブクエリのFROM句で指定するオブジェクトを子リレーション名とします。子リレーション名は参照項目作成時に指定したりしますが、標準で指定されているものだと、複数形にすることが多いです。
AccountからContactを引く時は以下の様になります。
SELECT a.Id, (SELECT c.Id FROM Contacts c) From Account a
ここで注意すべき点はここでの返り値がAccount1レコードにつき1行で返ってくることです。ですので、Contactは配列で返ってきます。なんで、これにアクセスしてAPEXでレコード操作しようなんて思うと2回For文回す必要が出てきます。
Account[] accounts =[SELECT a.Id, (SELECT c.Id FROM Contacts c) From Account a];
For(Account a: accounts){
For(Contact c:a.Contacts){
System.debug(c);
}
}
これで全てのAccountに紐づくContactが表示出来ます(意味なし)。a.Contactsでaに紐づくContactにアクセス出来るのがポイントでしょうか。
まとめ
普通のSQLに慣れてると最初戸惑いますが、慣れてくると案外直感的な操作なのかなとも思います。この辺りの操作を覚えるとレコード操作がとても楽になります。
最新記事 by Yujiro Hayashi (全て見る)
- SOQL入門 SOQLにおけるJoinの方法 - 2017-06-22
- マーケターの必要スキル、SQLをなるべく手軽に覚えよう!② SOQLを触ってみる - 2016-08-19
- 脱Excel!マーケターの必要スキル、SQLをなるべく手軽に覚えよう!① 何故Excelを辞めるのか - 2016-08-09