SOQL query con sottoquery
-
26-09-2019 - |
Domanda
Sto avendo difficoltà a raggiungere i risultati che voglio da una query Salesforce / Apex / SOQL.
che voglio: un elenco di oggetti contatto che contiene solo i contatti che sono CampaignMembers di una serie di campagne; e dovrebbero avere i dati da quel membro di campagna facilmente accessibile. (Il mio obiettivo finale è una pagina VF con una lista di tutti i contatti collegati ad una qualsiasi di queste campagne con una griglia che indica lo stato di ciascuna campagna.)
Queste lavoro:
Campaign[] cams = [SELECT id, name
FROM Campaign
WHERE parentid = '70170000000LRIe'];
System.debug(cams);
// returns ~4 Campaign objects
CampaignMember[] cmembers = [SELECT id, status, contactid, campaignid
FROM CampaignMember
WHERE campaignid in :cams];
System.debug(cmembers);
// returns about 40 CampaignMember objects.
Ecco il mio problema:
Contact[] members = [SELECT id, firstname, lastname,
(SELECT id, status, comment__c, campaignid
FROM Contact.CampaignMembers
WHERE campaignid in :cams)
FROM Contact];
System.debug(members);
// contains ALL Contacts in the DB, but I wanted filtered results.
System.debug(members[x].CampaignMembers);
// this is a contact I've verified has a qualifying CampaignMember, but the list is empty.
// UPDATE: CampaignMembers are now being returned, not sure what changed...
-
Perché non sono alcun CampaignMember oggetti che vengono restituiti dal subquery? - Perché non è la lista di contatto viene filtrata? (Beh, ovviamente b / c non c'è clausola WHERE in essa, ma che cosa clausola WHERE fornisce quello che voglio?)
So che potrei farlo facendo la query CampaignMember da sola e loop attraverso di essa per preparare una query di contatto, ma che sembra come un sacco di elaborazione supplementare quando una sottoquery dovrebbe funzionare.
Grazie!
Aggiorna
Gli oggetti CampaignMember ora stanno rivelando - stranamente -. Mi deve aver fissato qualche piccolo errore di battitura senza accorgersene (e sì, stanno tornando più colonne e che sembra andare bene)
Non riesco ancora a capire come filtrare la query di contatto, anche se ...
Soluzione
Si potrebbe utilizzare un semi-join su contatti per filtrare i contatti per il set che si desidera, qualcosa di simile
[select id, firstname, lastname,
(select id, status, comment__c, campaignid from CampaignMembers)
from contact where id in
(select contactId from campaignMember where campaignId in :cams];
Un'altra opzione sarebbe quella di guidare da campaignMmeber invece.
[select contact.id, contact.firstname, contact.lastname,
status, comment__c, campaignId from campaignMembers
where contactId !='' and campaignId in :cams];