You can use the following trigger to count the number of Contact records associated with an account record.
Note:
For existing records, do a one time data load with the count.
Sample Trigger:
trigger ContactCount on Contact (after insert, after update, after delete, after undelete) {
Map < Id, List< Contact > > mapAcctIdContactList = new Map < Id, List < Contact > >();
Map < Id, List< Contact > > mapAcctIdDelContactList = new Map < Id, List < Contact > >();
Set < Id > AcctIds = new Set < Id >();
if ( trigger.isInsert ) {
for(Contact Con : trigger.New) {
if ( String.isNotBlank( Con.AccountId ) ) {
if ( !mapAcctIdContactList.containsKey( Con.AccountId ) ) {
mapAcctIdContactList.put( Con.AccountId, new List < Contact >());
}
mapAcctIdContactList.get( Con.AccountId ).add( Con );
AcctIds.add( Con.AccountId );
}
}
}
if ( trigger.isUpdate ) {
for ( Contact Con : trigger.New ) {
Id oldAcctId = trigger.oldMap.get( Con.Id ).AccountId;
if ( String.isNotBlank ( Con.AccountId ) && Con.AccountId != oldAcctId ) {
if ( !mapAcctIdContactList.containsKey ( Con.AccountId ) ) {
mapAcctIdContactList.put ( Con.AccountId, new List < Contact >() );
}
mapAcctIdContactList.get( Con.AccountId ).add ( Con );
AcctIds.add ( Con.AccountId );
if ( !mapAcctIdDelContactList.containsKey ( oldAcctId ) ){
mapAcctIdDelContactList.put ( oldAcctId, new List < Contact >() );
}
mapAcctIdDelContactList.get( oldAcctId ).add( Con );
AcctIds.add ( oldAcctId );
} else if ( String.isBlank ( Con.AccountId ) && String.isNotBlank( oldAcctId ) ) {
if ( !mapAcctIdDelContactList.containsKey ( oldAcctId ) ){
mapAcctIdDelContactList.put ( oldAcctId, new List < Contact >() );
}
mapAcctIdDelContactList.get( oldAcctId ).add( Con );
AcctIds.add( oldAcctId );
}
}
}
if ( trigger.isUndelete) {
for ( Contact Con : trigger.new ) {
if ( String.isNotBlank( Con.AccountId ) ) {
if ( !mapAcctIdContactList.containsKey( Con.AccountId ) ) {
mapAcctIdContactList.put( Con.AccountId, new List < Contact >() );
}
mapAcctIdContactList.get( Con.AccountId ).add( Con );
AcctIds.add( Con.AccountId );
}
}
}
if ( trigger.isDelete) {
for( Contact Con : trigger.Old ) {
if ( String.isNotBlank( Con.AccountId ) ) {
if ( !mapAcctIdDelContactList.containsKey( Con.AccountId ) ) {
mapAcctIdDelContactList.put( Con.AccountId, new List < Contact >() );
}
mapAcctIdDelContactList.get( Con.AccountId ).add( Con);
AcctIds.add( Con.AccountId );
}
}
}
if ( AcctIds.size() > 0 ) {
List < Account > listAcct = new List < Account >();
listAcct = [ SELECT Id, Number_of_Contacts__c FROM Account WHERE Id IN : AcctIds ];
for ( Account acct : listAcct ) {
Integer noOfConts = 0;
if ( mapAcctIdContactList.containsKey( acct.Id ) ) {
noOfConts += mapAcctIdContactList.get( acct.Id ).size();
}
if ( mapAcctIdDelContactList.containsKey( acct.Id ) ) {
noOfConts -= mapAcctIdDelContactList.get( acct.Id ).size();
}
acct.Number_of_Contacts__c = acct.Number_of_Contacts__c == null ? noOfConts : ( acct.Number_of_Contacts__c + noOfConts );
}
update listAcct;
}
}