親から子へのリレーションクエリ

## **🚀 親から子へのリレーションクエリ（子オブジェクトの取得）**

SalesforceのSOQLでは、**親オブジェクトから関連する子オブジェクトを取得する**ことができます。  
これは **「サブクエリ」** を使用して表現され、**リレーション名（API参照名）** に注意が必要です。

---

# **1️⃣ 標準リレーション（親 → 子）**
Salesforceの標準オブジェクトでは、  
**親オブジェクトのAPI参照名** に **`(SELECT ...)` をサブクエリとして書く** ことで、関連する子オブジェクトを取得できます。

## **✅ 例：取引先（Account） → 商談（Opportunity）の関係**
- **取引先（Account）** は **商談（Opportunity）** の親
- 商談は、`AccountId` を使って取引先と紐づいている
- **親から子を取得する場合、API参照名は `Opportunities`（複数形） になる！**

---

### **🔹 SOQLクエリ（標準リレーション：親から子を取得）**
```apex
// 取引先（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クエリ（カスタムリレーション：親から子を取得）**
```apex
// プロジェクト（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` を使います。

---

### **🔹 例①: 子（商談）を持つ親（取引先）のみ取得**
```apex
// 商談を持つ取引先のみを取得
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)` で、商談を持つ取引先のみ取得！**

---

### **🔹 例②: 子（タスク）を持つ親（プロジェクト）のみ取得（カスタムオブジェクト）**
```apex
// タスクがあるプロジェクトのみを取得
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 子オブジェクト)` を使う**  

これらを押さえれば、**親から子へのリレーションクエリを自在に使いこなせます！🚀**