Your question is SQL Joins and Conditional Aggregations. Start with the requirements and the three tables on the right.
Run and submit as often as you like. When you're ready, talk me through your approach or go straight to the code.
Catalist needs a campaign-level view of outreach performance for campaigns launched during September 2025. Write a PostgreSQL query that joins campaigns, constituents, and outreach events, while preserving campaigns with no matching constituents or events.
| Column | Type | Description |
|---|---|---|
| campaign_idPK | INTEGER | Unique campaign identifier |
| campaign_name | VARCHAR(100) | Name of the Catalist outreach campaign |
| district | VARCHAR(50) | Geographic district |
| start_date | DATE | Campaign launch date |
| Column | Type | Description |
|---|---|---|
| constituent_idPK | INTEGER | Unique constituent identifier |
| campaign_id | INTEGER | Campaign assigned to the constituent |
| postal_code | VARCHAR(10) | Constituent postal code |
| Column | Type | Description |
|---|---|---|
| event_idPK | INTEGER | Unique outreach event identifier |
| constituent_id | INTEGER | Constituent contacted during the event |
| event_status | VARCHAR(20) | Outcome status of the outreach event |
| response | VARCHAR(20) | Recorded constituent response |
| duration_minutes | INTEGER | Duration of the outreach event |
| event_date | DATE | Date the outreach occurred |