So the end result I'm hoping to achieve is to do a Left Anti-Join in SOQL without using Roll-Up Summary fields or Apex. Here's the scenario:
We have 2 custom objects, say Property__c
and Connected_Device__c
.
Connected_Device__c
has the 2 following fields:
- A lookup field to
Property__c
- a picklist field named
Type__c
with the picklist values:'Hub', 'Thermostat', 'Garage'
meaning our property records will have a related list of connected devices. Here's the scenario:
-
Property A has 3 connected devices, one for each of the different
Type__c
values. -
Property B has 2 connected devices, one for
Thermostat
and one forGarage
.
If I wanted to query the properties that had at least 1 connected Hub devices, I could use the query:
SELECT Property__c, COUNT(Id) hubs
FROM Connected_Device__c
WHERE Type__c = 'Hub'
GROUP BY Property__c
HAVING COUNT(Id) >= 1
But what if I wanted to find all the properties that have 0 connected Hub devices but that still have other linked connected devices (i.e. Property B)?
I wouldn't be able to build a query on the Connected_Device__c
records that have Type__c = 'Hub'
, since the query result would always be empty.
And using a NOT()
statement (i.e. (NOT Type__c = 'Hub')
) would result in both property records being returned, since both have Thermostat
and Garage
connected devices.
I know that ultimately I could build a simpler SOQL query and then use logic in Apex to to get the result I want, or have Roll-Up Summaries on the object that count the number of Hub and non-Hub connected devices, but this is more of an exercise in determining if this is possible with SOQL alone.
Let me know if I need to add more to the question/clarify anything!
Best Answer
It'd be something like:
Note that you must use
AND
, asOR
isn't supported. TheId IN
andId NOT IN
syntaxes are incredibly useful for finding parent records that meet certain child criteria.