Count the number of child records on the each parent object
trigger ContactTrigger on Contact (after insert, after update, after delete, after undelete) { //---> above handling all states which could see a contact added to or removed from an account //---> on delete we use Trigger.Old, all else, Trigger.new List<Contact> contacts = Trigger.isDelete ? Trigger.old : Trigger.new; //---> the Set class rocks for finding the unique values in a list Set<Id> acctIds = new Set<Id>(); for (Contact c : contacts) { //yes, you can have a contact without an account if (c.AccountId != null) { acctIds.add(c.AccountId); } } List<Account> acctsToRollup = new List<Account>(); //****** Here is the Aggregate query...don't count in loops, let the DB do it for you***** for (AggregateResult ar : [SELECT AccountId AcctId, Count(id) ContactCount FROM Contact WHERE AccountId in: acctIds GROUP BY AccountId]){ Account a = new Account(); a.Id = (Id) ar.get('AcctId'); //---> handy trick for updates, set the id and update a.Contact_Count__c = (Integer) ar.get('ContactCount'); acctsToRollup.add(a); } //----> probably you'll want to do a little more error handling than this...but this should work. update acctsToRollup; }
Source: developer.salesforce.com