Salesforce SOQL中的Semi-Join和Anti-Join
半连接和反链接是SOQL里面一个宝,只要用的好,天天下班早
Semi-Join | 半连接
半连接(Semi-Join)指的是在SOQL语句的对比子句里面(也就是WHERE
部分),使用子查询(subquery
)的情况。
可能用到半连接的情况可能有:
- 获取某些具有特定阶段或者截至日期Opportunity的Account下面所有Contact信息
- 获取具有激活的Contract的Account下面所有的Opportunity信息
写法
有两种半连接:1)使用Id字段,2)使用外键(Lookup/Master-Detail关系等)
使用Id字段的半连接例子:
SELECT Id, Name FROM Account WHERE Id IN ( SELECT AccountId FROM Opportunity WHERE StageName = 'Closed Lost' )
使用外键的半连接例子:
SELECT Id FROM Task WHERE WhoId IN ( SELECT Id FROM Contact WHERE MailingCity = 'Twin Falls' )
Anti-Join | 反连接
反连接(Anti-Join)与半连接非常类似,只是不同于半连接使用的比较关键字为IN
, 反连接使用的比较关键字为NOT IN
。其余部分包括写法、限制等是一致的,不再赘述。
两种写法
使用Id字段的半连接例子:
ELECT Id, (Select Id, Amount, CloseDate FROM Opportunities) FROM Account WHERE Id NOT IN ( SELECT AccountId FROM Contact WHERE LastName LIKE 'Trump%' )
使用外键的半连接例子:
SELECT Id, Name, Phone, Email FROM Contact WHERE AccountId NOT IN ( SELECT AccountId FROM Opportunity WHERE CloseDate < Last_Week )
限制
- 在主语句的
WHERE
分句中,不能超过2个IN
或NOT IN
语句 - 不能在半连接或者反连接前使用
NOT
操作符。若有这种情况,可以考虑把半连接转换为反连接,或者反连接转换为全连接 - 必须是Id字段或者外键,诸如
... Where Account.Id IN (...)
是非法的 - 子查询的查询字段必须与主查询对应的字段
SObject
一致,是且必须是对应的外键 - 子查询的字段条数不受限制,但是主查询条数仍收到限制
- 半连接或者反连接不能嵌套使用,即不能在半连接/反连接中再使用半连接或者反连接
- 子查询不能使用
OR
- 子查询不支持
COUNT
, 'FOR UPDATE,
ORDER BY,
LIMIT` 下列对象不支持:
- ActivityHistory
- Attachments
- Event
- EventAttendee
- Note
- OpenActivity
- Tags (AccountTag, ContactTag, and all other tag objects)
- Task
详情可以查看SOQL and SOSL Reference
以下章节:
Semi-Joins with IN and Anti-Joins with NOT IN