I am trying to set up a trigger that updates a field that keeps the count of the related cases. But since it is my 1st trigger I am having a hard time to get it work. I googled some examples and tried to mimic the most similar one. Since I havent understood completely how to code a trigger, I cant go forward anymore.

This is what I got and hope you can help:

  //Objective: count the number of related cases through the Standard Field Parent (lookup)
  //Everytime a case is inserted, updated or delete, this trigger should update the field Number_of_Related_Cases__c 
  //with a count. 

  //Define the trigger and fire it up on insert and update    
  trigger Count_Related_Cases on Case (after insert, after update, after delete) {

  //Create a list named "rc" that will contain Case Records
  //Create a variable named "casid" that will hold the Parent ID
  //Store on caseid the Parent ID for the first case on the list rc     
  Case [] rc = Trigger.new; 
  ID caseid = null;
  caseid = rc[0].Parent;

  //Create a variable that will hold the count of cases that have the same Parent Case ID            
  Integer i = [select count() from Case where Parent = :caseid]; 

  //Create a list "s" that will have all the "Master Cases" that have at least one related Case.     
  Case [] s =[select id,Number_of_Related_Cases__c from Case where id = :caseid];

  //Update the Master Case field Number_of_Related_Cases__c with the count "i"    
  s[0].Number_of_Related_Cases__c = i;         

  // write to database    
  update s[0];     

2 Answers 2


I would approach it like this - that way it will be bulkified, and handle cases having their parent removed:

trigger Count_Related_Cases on Case (after insert, after update, after delete) {

//build list of parent case ids
    Set<Id> ParentIds = new Set<Id>();

  //If insert or update, use trigger.new
  if (trigger.isinsert || trigger.isupdate) {

  //if case has parent, add to set of parentids
  for (Case c: Trigger.New) {

      if(c.ParentId != null) {

  //if case previously had parent, but no longer does, also add so we can recalc
  if (trigger.isupdate) {

      if (trigger.oldmap.get(c.id).parentid != null && c.ParentId == null) {



  //if delete, make sure we update parent
  else if (trigger.isdelete) {

  for (Case c: Trigger.Old) {

      if(c.ParentId != null) {


  //then query for parent cases, and do inner query for related cases
    List<Case> pcount = [Select Id, (Select Id from Cases) From CASE where Id IN :ParentIds];

              //use size of inner cases to set number count
              for (Case pc: pcount) {
              pc.Number_of_Related_Cases__c = pc.cases.size();
     //update parents         
    update pcount;
  • Is there something else that needs to be done to launch this trigger. I'm not familiar with triggers and need to know how to move this from the sandbox to production.
    – user2523
    Commented Mar 12, 2013 at 20:20
  • @Rachel - you will need to write a unit test, but that's a whole other question!
    – metadaddy
    Commented Mar 12, 2013 at 21:05

This does the job and copes with reparenting as well as parent deletion. I don't test for null parent ids but I guess you could remove null from the set of ids prior to the Select but I don't find it a problem.

trigger CaseRollup on Case (after insert, after update, after delete) {

    Set<Id> parentList = new Set<Id>();

    if (Trigger.isUpdate || Trigger.isInsert) {
        for (Case c : Trigger.new) {
    if (Trigger.isUpdate || Trigger.isDelete) {
        for (Case c : Trigger.old) {

    List<Case> cases = [SELECT Id, (SELECT Id FROM Cases) FROM Case WHERE Id IN :parentList];

    for (Case c : cases) {
        c.Case_Count__c = c.Cases.size();

    update cases;   

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .