function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Vitaliy Beliy 15Vitaliy Beliy 15 

list through SOQL. 2 levels of hierarchy// Help please

Hello everyone,
I have 3 custom objects. Car__c, Service__c, Action__c,
I would really like to know how to get a list of all cars where Action__c.category = 'SOME VALUE'.
Link mapping looks like this
User-added image
Best Answer chosen by Vitaliy Beliy 15
Maharajan CMaharajan C
Hi Vitally,

Try the below ways:

I think it's not possible in single query.

Create the Formula fielld in  Action Object to populate the Car Detail.

Formula Field (return type text) :   Action > Service > Car.Id   . 

Then the below code snippet will help you to fetch the Car List :

set<Id> carIds = new set<Id>();
for(Action__c act : [Select Id, Name, Formula Field  from Action__c where category =: 'Some Value' AND Formula Field != null ])
{
       carIds.add(ID.ValueOf(act.Formula Field));
}
List<car__c> carList =[Select Id, Name from car__c where ID IN: carIds];



If you don't want to create the Formula Field then you can go with the any below approaches:

==================== OR ===============

List<car__c> carList = new List<car__c>();
for(car__c c : [Select Id,Name,(Select Id from Service__r where Id IN : (Select Service__c from Action__c where category =: 'Some Value')) from car__c] )
{
    if(c.Service__r.size() > 0)
        {
               carList.add(c);
        }
}



==================== OR  ==============
List<car__c> carList = new List<car__c>();
Set<Id> carSet = new set<Id>();
for(Service  act : [Select car__c from Service__c where ID IN: (Select Service__c from Action__c where category =: 'Some Value'))])
{
    carSet.add(act.car__c);
}

carList = [Select Id,Name from car__c wher Id IN: carSet];

==================== OR  ==============

List<car__c> carList = new List<car__c>();
Set<Id> serSet = new set<Id>();
Set<Id> carSet = new set<Id>();
for(Action__c act: [Select Service__c from Action__c where category =: 'Some Value'])
{
    serSet.add(act.Service__c);
}
for(Service  ser : [Select car__c from Service__c where ID IN: serSet)])
{
    carSet.add(act.car__c);
​​​​​​​}

carList = [Select Id,Name from car__c wher Id IN: carSet];


Thanks,
Maharajan.C

All Answers

Maharajan CMaharajan C
Hi Vitally,

Try the below ways:

I think it's not possible in single query.

Create the Formula fielld in  Action Object to populate the Car Detail.

Formula Field (return type text) :   Action > Service > Car.Id   . 

Then the below code snippet will help you to fetch the Car List :

set<Id> carIds = new set<Id>();
for(Action__c act : [Select Id, Name, Formula Field  from Action__c where category =: 'Some Value' AND Formula Field != null ])
{
       carIds.add(ID.ValueOf(act.Formula Field));
}
List<car__c> carList =[Select Id, Name from car__c where ID IN: carIds];



If you don't want to create the Formula Field then you can go with the any below approaches:

==================== OR ===============

List<car__c> carList = new List<car__c>();
for(car__c c : [Select Id,Name,(Select Id from Service__r where Id IN : (Select Service__c from Action__c where category =: 'Some Value')) from car__c] )
{
    if(c.Service__r.size() > 0)
        {
               carList.add(c);
        }
}



==================== OR  ==============
List<car__c> carList = new List<car__c>();
Set<Id> carSet = new set<Id>();
for(Service  act : [Select car__c from Service__c where ID IN: (Select Service__c from Action__c where category =: 'Some Value'))])
{
    carSet.add(act.car__c);
}

carList = [Select Id,Name from car__c wher Id IN: carSet];

==================== OR  ==============

List<car__c> carList = new List<car__c>();
Set<Id> serSet = new set<Id>();
Set<Id> carSet = new set<Id>();
for(Action__c act: [Select Service__c from Action__c where category =: 'Some Value'])
{
    serSet.add(act.Service__c);
}
for(Service  ser : [Select car__c from Service__c where ID IN: serSet)])
{
    carSet.add(act.car__c);
​​​​​​​}

carList = [Select Id,Name from car__c wher Id IN: carSet];


Thanks,
Maharajan.C
This was selected as the best answer
Deepali KulshresthaDeepali Kulshrestha
Hi Vitaliy,

1.I've gone through your requirement and you can go reverse in the hierarchy (i.e. go from child to parent because in this type we can access up to 5 levels)
2. Below is the example of how to map Action__c with Car__c.

(Note---> there should be Master-Detail Relationship)

Apex Code--->

Map<id,List<Action__c>> CarIdVSActionMap=new Map<id,List<Action__c>>();
            
            for(Action__c action:[select id,Service__c.CarID__c from Action__c 
                                              where Service__c.CarID__c!=null ])
            {
                if(CarIdVSActionMap.containskey(action.Service__c.CarID__c))
                {
                    CarIdVSActionMap.get(action.Service__c.CarID__c).add(action);
                }
                else
                {
                    CarIdVSActionMap.put(action.Service__c.CarID__c,new List<Action__c>());
                    CarIdVSActionMap.get(action.Service__c.CarID__c).add(action);
                }
            }
            
            

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks and Regards,
Deepali Kulshrestha
www.kdeepali.com