2019年4月

半连接和反链接是SOQL里面一个宝,只要用的好,天天下班早

Semi-Join | 半连接

半连接(Semi-Join)指的是在SOQL语句的对比子句里面(也就是WHERE部分),使用子查询(subquery)的情况。

可能用到半连接的情况可能有:

  1. 获取某些具有特定阶段或者截至日期Opportunity的Account下面所有Contact信息
  2. 获取具有激活的Contract的Account下面所有的Opportunity信息

写法
有两种半连接:1)使用Id字段,2)使用外键(Lookup/Master-Detail关系等)

  1. 使用Id字段的半连接例子:

    SELECT Id, Name 
    FROM Account 
    WHERE Id IN 
      ( SELECT AccountId
     FROM Opportunity
     WHERE StageName = 'Closed Lost' 
      )
  2. 使用外键的半连接例子:

    SELECT Id
    FROM Task 
    WHERE WhoId IN 
      (
     SELECT Id
     FROM Contact
     WHERE MailingCity = 'Twin Falls'
      )

Anti-Join | 反连接

反连接(Anti-Join)与半连接非常类似,只是不同于半连接使用的比较关键字为IN, 反连接使用的比较关键字为NOT IN。其余部分包括写法、限制等是一致的,不再赘述。

两种写法

  1. 使用Id字段的半连接例子:

    ELECT Id, (Select Id, Amount, CloseDate FROM Opportunities)
    FROM Account
    WHERE Id NOT IN
      (
     SELECT AccountId
     FROM Contact
     WHERE LastName LIKE 'Trump%'
      )
  2. 使用外键的半连接例子:

    SELECT Id, Name, Phone, Email
    FROM Contact
    WHERE AccountId NOT IN 
      (
     SELECT AccountId
     FROM Opportunity
     WHERE CloseDate < Last_Week
      )

限制

  1. 在主语句的WHERE分句中,不能超过2INNOT IN语句
  2. 不能在半连接或者反连接前使用NOT操作符。若有这种情况,可以考虑把半连接转换为反连接,或者反连接转换为全连接
  3. 必须是Id字段或者外键,诸如... Where Account.Id IN (...)是非法的
  4. 子查询的查询字段必须与主查询对应的字段SObject一致,是且必须是对应的外键
  5. 子查询的字段条数不受限制,但是主查询条数仍收到限制
  6. 半连接或者反连接不能嵌套使用,即不能在半连接/反连接中再使用半连接或者反连接
  7. 子查询不能使用OR
  8. 子查询不支持COUNT, 'FOR UPDATE, ORDER BY, LIMIT`
  9. 下列对象不支持:

    • 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