🚀 親から子へのリレーションクエリ(子オブジェクトの取得)
SalesforceのSOQLでは、親オブジェクトから関連する子オブジェクトを取得することができます。
これは 「サブクエリ」 を使用して表現され、リレーション名(API参照名) に注意が必要です。
1️⃣ 標準リレーション(親 → 子)
Salesforceの標準オブジェクトでは、
親オブジェクトのAPI参照名 に (SELECT ...) をサブクエリとして書く ことで、関連する子オブジェクトを取得できます。
✅ 例:取引先(Account) → 商談(Opportunity)の関係
- 取引先(Account) は 商談(Opportunity) の親
- 商談は、
AccountIdを使って取引先と紐づいている - 親から子を取得する場合、API参照名は
Opportunities(複数形) になる!
🔹 SOQLクエリ(標準リレーション:親から子を取得)
// 取引先(Account)ごとに関連する商談(Opportunity)を取得
List<Account> accounts = [SELECT Id, Name, (SELECT Id, Name, Amount FROM Opportunities) FROM Account];
for (Account acc : accounts) {
System.debug('取引先名: ' + acc.Name);
for (Opportunity opp : acc.Opportunities) {
System.debug(' - 商談名: ' + opp.Name + ', 金額: ' + opp.Amount);
}
}
🔹 ポイント
✅ サブクエリ (SELECT ... FROM 子オブジェクトAPI参照名) を使う
✅ 標準オブジェクトでは、リレーション名は複数形(例:Opportunities)
✅ acc.Opportunities は List<Opportunity> 型(子オブジェクトのリスト)
2️⃣ カスタムリレーション(親 → 子)
カスタムオブジェクトの場合、子オブジェクトのリレーション名のAPI参照名に __r がつく ため、注意が必要です。
✅ 例:プロジェクト(Project__c) → タスク(Task__c)の関係
-
Task__c(子オブジェクト)にはProject__cという親オブジェクトの参照項目がある -
親から子を取得するときのAPI参照名は
Tasks__r(__r付き) になる!
🔹 SOQLクエリ(カスタムリレーション:親から子を取得)
// プロジェクト(Project__c)ごとに関連するタスク(Task__c)を取得
List<Project__c> projects = [SELECT Id, Name, (SELECT Id, Name, Status__c FROM Tasks__r) FROM Project__c];
for (Project__c proj : projects) {
System.debug('プロジェクト名: ' + proj.Name);
for (Task__c task : proj.Tasks__r) {
System.debug(' - タスク名: ' + task.Name + ', ステータス: ' + task.Status__c);
}
}
🔹 ポイント
✅ カスタムオブジェクトのリレーション名には __r を使う
✅ proj.Tasks__r は List<Task__c> 型(子オブジェクトのリスト)
3️⃣ 親オブジェクトのリレーション項目の参照の仕方
| リレーションの種類 | 子オブジェクトのAPI参照名 | 親→子のリレーション名(サブクエリ用) |
|---|---|---|
| 標準リレーション |
AccountId(商談) |
Opportunities(複数形) |
| カスタムリレーション |
Project__c(タスク) |
Tasks__r(__r が付く) |
4️⃣ 親から子に向かう場合に使用するデータ型
親オブジェクトから子オブジェクトを取得した場合、子オブジェクトはリスト(List<SObject>)として取得されます。
✅ データ型の違い
| 取得するもの | データ型 | 例(Account → Opportunity) |
|---|---|---|
| 親のID | Id |
acc.Id |
| 親のレコード | Account |
Account acc |
| 子オブジェクトのリスト | List<Opportunity> |
acc.Opportunities |
| 子の個別レコード | Opportunity |
acc.Opportunities[0] |
5️⃣ 関連づけられた子を持つ親のみを取得
子オブジェクトを持つ親オブジェクト のみを取得 するには、HAVING COUNT() や EXISTS を使います。
🔹 例①: 子(商談)を持つ親(取引先)のみ取得
// 商談を持つ取引先のみを取得
List<Account> accounts = [SELECT Id, Name, (SELECT Id, Name FROM Opportunities) FROM Account WHERE Id IN (SELECT AccountId FROM Opportunity)];
for (Account acc : accounts) {
System.debug('商談がある取引先名: ' + acc.Name);
}
✅ サブクエリ WHERE Id IN (SELECT AccountId FROM Opportunity) で、商談を持つ取引先のみ取得!
🔹 例②: 子(タスク)を持つ親(プロジェクト)のみ取得(カスタムオブジェクト)
// タスクがあるプロジェクトのみを取得
List<Project__c> projects = [SELECT Id, Name, (SELECT Id, Name FROM Tasks__r) FROM Project__c WHERE Id IN (SELECT Project__c FROM Task__c)];
for (Project__c proj : projects) {
System.debug('タスクがあるプロジェクト名: ' + proj.Name);
}
✅ カスタムリレーションのAPI参照名 (Project__c) を正しく指定する!
📌 まとめ
| 内容 | 記述例 |
|---|---|
| 標準リレーションで子を取得 | [SELECT Id, Name, (SELECT Id, Name FROM Opportunities) FROM Account] |
| カスタムリレーションで子を取得 | [SELECT Id, Name, (SELECT Id, Name FROM Tasks__r) FROM Project__c] |
| 子を持つ親のみを取得(標準) | [SELECT Id, Name FROM Account WHERE Id IN (SELECT AccountId FROM Opportunity)] |
| 子を持つ親のみを取得(カスタム) | [SELECT Id, Name FROM Project__c WHERE Id IN (SELECT Project__c FROM Task__c)] |
🎯 重要ポイント
✅ 親→子のリレーションはサブクエリ (SELECT ... FROM 子オブジェクトAPI参照名) を使う
✅ 標準オブジェクトのリレーションは複数形(例:Opportunities)
✅ カスタムオブジェクトのリレーションは __r が付く(例:Tasks__r)
✅ 子を持つ親のみを取得するには WHERE Id IN (SELECT ... FROM 子オブジェクト) を使う
これらを押さえれば、親から子へのリレーションクエリを自在に使いこなせます!🚀