Группировка предложений WHERE в Codeigniter

Я хочу создать следующий код SQL, используя Active Records в Codeigniter:

WHERE name != 'Joe' AND (age < 69 OR id > 50) 

Выполнение следующего, кажется, насколько я могу получить, я не могу понять, как их группировать

 $this->db->select()->from('users')->where('name !=', 'Joe')->where('age <', 69)->or_where('id <', $id); 

Есть идеи? Мой SQL-запрос слишком сложный, поэтому я не хочу переписывать все в традиционном SQL.

ОБНОВИТЬ

Мой SQL-код динамически генерируется в зависимости от значений некоторых параметров, переданных в модельный метод. Проблема с невозможностью использования круглых скобок вызывает проблему, поскольку приоритет оператора таков, что AND сначала оценивается OR .

* Вот фрагмент моего активного кода записи, где есть и другие коды до и после него:

  ... some $this->db->where() ... ... some $this->db->where() ... if($price_range) { $price_array = explode('.', $price_range); for($i = 0; $i < count($price_array); $i++) { if($i == 0) { $this->db->where('places.price_range', $price_array[$i]); } else { $this->db->or_where('places.price_range', $price_array[$i]); } } } ... some $this->db->where() ... ... some $this->db->where() ... 

Проблема возникает из-за того, что я использую $this->db->or_where() который вводит предложение OR , которое бросает приоритет оператора в беспорядок, не имея возможности использовать ( ) для изменения порядка.

** Есть ли способ решить это? **

Вы можете использовать одну большую строку.

$this->db->select()->from('users')->where("name != 'Joe' AND (age < 69 OR id > 50) ");

В Codeigniter 3.0.3 вы можете сделать это просто так:

 $this->db->select() ->from('users') ->where('name !=', 'Joe') ->group_start() // Open bracket ->where('age <', 69) ->or_where('id <', $id) ->group_end(); // Close bracket 

Возможно, это может помочь

Группировка где clauses не в CI по умолчанию. Вы должны расширить ядро ​​и добавить способность. Я сделал это, сделав что-то следующим образом:

 class MY_DB_mysql_driver extends CI_DB_mysql_driver { public function __construct($params) { parent::__construct($params); } /** * This function will allow you to do complex group where clauses in to c and (a AND b) or ( d and e) * This function is needed as else the where clause will append an automatic AND in front of each where Thus if you wanted to do something * like a AND ((b AND c) OR (d AND e)) you won't be able to as the where would insert it as a AND (AND (b...)) which is incorrect. * Usage: start_group_where(key,value)->where(key,value)->close_group_where() or complex queries like * open_bracket()->start_group_where(key,value)->where(key,value)->close_group_where() * ->start_group_where(key,value,'','OR')->close_group_where()->close_bracket() would produce AND ((a AND b) OR (d)) * @param $key mixed the table columns prefix.columnname * @param $value mixed the value of the key * @param $escape string any escape as per CI * @param $type the TYPE of query. By default it is set to 'AND' * @return db object. */ function start_group_where($key,$value=NULL,$escape,$type="AND") { $this->open_bracket($type); return parent::_where($key, $value,'',$escape); } /** * Strictly used to have a consistent close function as the start_group_where. This essentially callse the close_bracket() function. */ function close_group_where() { return $this->close_bracket(); } /** * Allows to place a simple ( in a query and prepend it with the $type if needed. * @param $type string add a ( to a query and prepend it with type. Default is $type. * @param $return db object. */ function open_bracket($type="AND") { $this->ar_where[] = $type . " ("; return $this; } /** * Allows to place a simple ) to a query. */ function close_bracket() { $this->ar_where[] = ")"; return $this; } } 

Применение:

 group_where_start(key,value)->where(key,value)->group_where_close() 

или

сложные запросы, такие как

 open_bracket()->start_group_where(key,value)->where(key,value)->close_group_where()->start_group_where(key,value,'','OR')->close_group_where()->close_bracket() would produce AND ((a AND b) OR (d)) 

То, что я сделал, – это дублировать предложение и после того, где оно фактически совпадает с длинным выбором строки.

 $this->db->select() ->from('users') ->where('name !=', 'Joe') ->where('age <', 69) ->or_where('id <', $id) ->where('name !=', 'Joe'); 

Вероятно, один большой струнный путь лучше.

У CI3 есть все, что вам нужно!

 $this->db->select('*')->from('my_table') ->group_start() ->where('a', 'a') ->or_group_start() ->where('b', 'b') ->where('c', 'c') ->group_end() ->group_end() ->where('d', 'd') ->get(); 

https://www.codeigniter.com/userguide3/database/query_builder.html#query-grouping

Решаемые. Динамически генерировать SQL-запрос и подключать его к $this->db->where() . Спасибо, парни!