Вот мой запрос в Codeigniter
$this->db->select('p.*,u.firstname, u.lastname,s.title AS industry, pt.type_name , al.length_value',FALSE); $this->db->from($this->_tbl_projects . ' as p'); $this->db->join($this->_tbl_client_details . ' as c', 'c.id = p.client_id', 'left'); $this->db->join($this->_tbl_users . ' as u', 'u.id = c.user_id', 'left'); $this->db->join($this->_tbl_project_types . ' as pt', 'pt.project_type_id = p.project_type_id', 'left'); $this->db->join($this->_tbl_specializations . ' as s', 's.specialization_id = p.specialization_id', 'left'); $this->db->join($this->_tbl_article_length . ' as al', 'al.article_length_id = p.article_length_id', 'left'); $this->db->order_by("CASE p.submit_to WHEN '' THEN 0 WHEN 'writer' THEN 1 ELSE 2 END, p.request_end_date asc",FALSE);
Распечатать
SELECT p.*, u.firstname, u.lastname, s.title AS industry, pt.type_name, al.length_value FROM (`projects` as p) LEFT JOIN `client_details` as c ON `c`.`id` = `p`.`client_id` LEFT JOIN `users` as u ON `u`.`id` = `c`.`user_id` LEFT JOIN `project_types` as pt ON `pt`.`project_type_id` = `p`.`project_type_id` LEFT JOIN `specializations` as s ON `s`.`specialization_id` = `p`.`specialization_id` LEFT JOIN `article_length` as al ON `al`.`article_length_id` = `p`.`article_length_id` WHERE `p`.`client_id` = '26' AND `p`.`status` IN (2, 3) ORDER BY `CASE` p.submit_to WHEN '' THEN 0 WHEN 'writer' THEN 1 ELSE 2 END, `p`.`request_end_date` asc
Здесь, в печатном запросе, CASE печатается `CASE` , поэтому sql бросает ошибку.
Как я могу это решить?
Структура поля submit_to
submit_to enum('','writer','students') NOT NULL
Документация CodeIgniter указывает, что оператор case в предложении order by не поддерживается в классе Active Record. Я бы рекомендовал рефакторинг SQL-вызова, чтобы оператор case был частью предложения select. Что-то вроде следующего должно сделать трюк.
$this->db->select("p.*,u.firstname, u.lastname,s.title AS industry, pt.type_name, al.length_value, CASE p.submit_to WHEN 'writer' THEN 2 WHEN 'students' THEN 1 ELSE 0 END AS ordered_submit_to",FALSE); $this->db->from($this->_tbl_projects . ' as p'); $this->db->join($this->_tbl_client_details . ' as c', 'c.id = p.client_id', 'left'); $this->db->join($this->_tbl_users . ' as u', 'u.id = c.user_id', 'left'); $this->db->join($this->_tbl_project_types . ' as pt', 'pt.project_type_id = p.project_type_id', 'left'); $this->db->join($this->_tbl_specializations . ' as s', 's.specialization_id = p.specialization_id', 'left'); $this->db->join($this->_tbl_article_length . ' as al', 'al.article_length_id = p.article_length_id', 'left'); $this->db->order_by('ordered_submit_to', 'ASC'); $this->db->order_by('p.request_end_date', 'ASC');
Я понял, как избежать выхода из слова CASE .
Вы можете изменить переменную $ _reserved_identifiers внутри класса CI_DB_driver . Если вы не хотите изменять весь файл, вы можете просто изменить его внутри класса Model непосредственно перед этим запросом.
$this->db->_reserved_identifiers = array('*','CASE'); $this->db->select('p.*,u.firstname, u.lastname,s.title AS industry, pt.type_name , al.length_value',FALSE); $this->db->from($this->_tbl_projects . ' as p'); $this->db->join($this->_tbl_client_details . ' as c', 'c.id = p.client_id', 'left'); $this->db->join($this->_tbl_users . ' as u', 'u.id = c.user_id', 'left'); $this->db->join($this->_tbl_project_types . ' as pt', 'pt.project_type_id = p.project_type_id', 'left'); $this->db->join($this->_tbl_specializations . ' as s', 's.specialization_id = p.specialization_id', 'left'); $this->db->join($this->_tbl_article_length . ' as al', 'al.article_length_id = p.article_length_id', 'left'); $this->db->order_by("CASE p.submit_to WHEN '' THEN 0 WHEN 'writer' THEN 1 ELSE 2 END, p.request_end_date asc",FALSE);
(Я не знаю, работает ли она на ветке 3.x, она работает хорошо на ветке 2.x)
Я нашел хорошее решение в другом ответе на SO, поэтому, если вы приземлились на этой странице и не нашли этого, я переведу его здесь.
Вы можете использовать оператор case, если вы заключите оператор case в круглые скобки .
$this->db->order_by(" (CASE p.submit_to WHEN '' THEN 0 WHEN 'writer' THEN 1 ELSE 2 END), p.request_end_date asc" );
Я тестировал сегодня и работает.
Вы можете использовать его, как вы сказали, когда используете второй параметр FALSE, чтобы отключить экранирование.
$this->db->order_by("CASE p.submit_to WHEN '' THEN 0 WHEN 'writer' THEN 1 ELSE 2 END, p.request_end_date asc",FALSE);
Приветствую.