0

I am trying to build a query using query builder with complex nested AND and OR conditions. Here is what I have written so far.

$cond_arr = array();
$cond_arr['VehicleBrandModels.status'] = 1;
$query = $this->VehicleBrandModels->find();
$query->hydrate(false);
$query->select($this->VehicleBrandModels);
$query->where($cond_arr);
$VBM_data = $query->toArray();

This will generate a query like below

SELECT * FROM vehicle_brand_models WHERE status = 1;

I want to generate a query with nested AND & OR conditions like below

SELECT * FROM vehicle_brand_models WHERE status = 1 AND ((overall_rating > 0 AND overall_rating < 2) OR (overall_rating >= 2 AND overall_rating < 4) OR (overall_rating >= 4 AND overall_rating <= 5));

Can anybody help to solve how to achieve this in CAKEPHP 3.0 Query builder?

1 Answers1

1

The simplest solution is the following

$cond_arr = [
    'VehicleBrandModels.status' => 1, 
    'OR' => [
        ['overall_rating >' =>  0, 'overall_rating <' => 2],
        ['overall_rating >=' => 2, 'overall_rating <' => 4],              
        ['overall_rating >=' => 4, 'overall_rating <=' => 5]
    ]
];

there is a more 'cake' way and if I'll have time I will post it.

But note that from what I see all your OR conditions overlap and you can simply do

 $cond_arr = [
    'VehicleBrandModels.status' => 1, 
    'overall_rating >' =>  0, 
    'overall_rating <=' => 5
];

edit: as primised here's the more cake way using query expressions

$query->where(function($exp, $q) {
    $exp = $exp->eq('VehicleBrandModels.status', 1);
    $conditions1 = $exp->and_([])
        ->gt('overall_rating ', 0)
        ->lte('overall_rating ', 2);
    $conditions2 = $exp->and_([])
        ->gt('overall_rating ', 2)
        ->lte('overall_rating ', 4);
    $conditions3 = $exp->and_([])
        ->gt('overall_rating ', 4)
        ->lte('overall_rating ', 5);
    $orConditions = $exp->or_([$conditions1, $conditions2, $conditions3]);
    $exp->add($orConditions);
    return $exp;
});

still some conditions are overlapping

arilia
  • 9,373
  • 2
  • 20
  • 44