Кодовые обозначения в динамическом запросе Active Record
Я создаю запрос, подобный следующему, используя ActiveRecord
SELECT * FROM (`foods`) WHERE `type` = 'fruits' AND
`tags` LIKE '%green%' OR `tags` LIKE '%blue%' OR `tags` LIKE '%red%'
Число tags
и значения неизвестны. Массивы создаются динамически. Ниже я добавил возможный массив.
$tags = array (
'0' => 'green'.
'1' => 'blue',
'2' => 'red'
);
Имея массив тегов, я использую следующий цикл для создания запроса, который я разместил сверху.
$this->db->where('type', $type); //var type is retrieved from input value
foreach($tags as $tag):
$this->db->or_like('tags', $tag);
endforeach;
Проблема: мне нужно добавить круглые скобки вокруг предложений LIKE
, как показано ниже:
SELECT * FROM (`foods`) WHERE `type` = 'fruits' AND
(`tags` LIKE '%green%' OR `tags` LIKE '%blue%' OR `tags` LIKE '%red%')
Я знаю, как это сделать, если содержимое в круглых скобках было статичным, но цикл foreach отбрасывает меня.
Ответы
Ответ 1
Из вики-страницы CI:
Функция Codeignign ActiveRecord позволяет создавать SQL-запросы относительно просто и независимый от базы данных, однако isno конкретная поддержка для включения скобки в запросе SQL.
Например, если вы хотите, чтобы оператор where выходил аналогично следующему:
WHERE (field1 = value || field2 = value) AND (field3 = value2 || field4 = value2)
Это можно обойти, подав строку в функцию CI- > db- > where(), в этом случае вам нужно будет специально избежать ваших значений.
См. следующий пример:
$value=$this->db->escape($value);
$value2=$this->db->escape($value2);
$this->db->from('sometable');
$this->db->where("($field = $value || $field2 = $value)");
$this->db->where("($field3 = $value2 || $field4 = $value2)");
$this->db->get();
Для предложений LIKE можно использовать одноразовое обходное решение:
$this->db->where("($field LIKE '%$value%' || $field2 LIKE '%$value%')");
$this->db->where("($field3 LIKE '%$value2%' || $field4 LIKE '%$value2%')");
Ответ 2
В CI 3.0-dev вы можете добавлять группы в запрос:
$this->db->select('id, title')
->group_start()
->or_like([ 'title' => $s, 'id' => $s ])
->group_end()
->where([ 'b_del' => 0 ]);
Выдает:
SELECT `id`, `title`, `venda1`
FROM `itens`
WHERE
(
`title` LIKE '%a%' ESCAPE '!'
OR `id` LIKE '%a%' ESCAPE '!'
)
AND `b_del` =0
Ответ 3
Одна из лучших возможностей для сохранения вашего запроса, когда вы применяете многократное предложение where или. where.
$this->db->group_start();
$this->db->where();
$this->db->or_where();
$this->db->group_end();
Счастливое кодирование.:)
Ответ 4
Отключение решения Silencer, я написал крошечную функцию, помогающую строить подобные условия
function make_like_conditions (array $fields, $query) {
$likes = array();
foreach ($fields as $field) {
$likes[] = "$field LIKE '%$query%'";
}
return '('.implode(' || ', $likes).')';
}
Вы бы использовали его следующим образом:
$search_fields = array(
'field_1',
'field_2',
'field_3',
);
$query = "banana"
$like_conditions = make_like_conditions($search_fields, $query);
$this->db->from('sometable')
->where('field_0', 'foo')
->where($like_conditions)
->get()
Ответ 5
Просто добавив свое успешное решение:
$this->db->where("(table.field = $variable OR table.field IS NULL)");
Ответ 6
Вы не можете добавить круглые скобки в ActiveRecord, но, возможно, WHERE IN - это то, что вы ищете?
$names = array('Frank', 'Todd', 'James');
$this->db->where_in('username', $names);
// Produces: WHERE username IN ('Frank', 'Todd', 'James')
Ответ 7
$likes = array (
'0' => 'green'.
'1' => 'blue',
'2' => 'red'
);
$where_like = "(";
$or_counter = 1;
foreach($likes as $like_key => $like_val):
$or_content = ($or_counter > 1) ?'OR': '';
$newlikeval = $this->db->escape_like_str($like_val);
$where_like .= $or_content." `$like_key` LIKE '%$newlikeval%' ";
$or_counter++;
endforeach;
$where_like .= ")";
$this->db->where($where_like);