2014-07-31 13 views
5

Hier meine Frage CodeigniterCodeigniter: Fehler in ORDER BY CASE Abfrage

in ist
$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); 

Es

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 

Hier in gedruckter Abfrage ausdrucken, CASE von `CASE wird gedruckt `, so sql wirft Fehler.

Wie kann ich es lösen?

Struktur submit_to Feld ist

submit_to enum('','writer','students') NOT NULL 

Antwort

8

Die CodeIgniter Dokumentation Fall Erklärungen Klausel in der Reihenfolge angibt, nicht innerhalb der Active Record-Klasse unterstützt. Ich würde empfehlen, den SQL-Aufruf zu refaktorieren, so dass die case-Anweisung Teil der select-Klausel ist. Etwas wie das folgende sollte den Trick tun.

$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'); 
+0

Danke für die Antwort. Ihre Aktualisierungen funktionieren, geben aber kein Ergebnis in der richtigen Reihenfolge. Ich will Daten, um submit_to = '' dann submit_to = 'Studenten' und letzten submit_to = 'Schreiber'. Ihre Updates gibt das Ergebnis in dieser Reihenfolge 1. '' 2. 'Schreiber' 3. 'Studenten'. – Napster

+0

Aktualisiert, um Ihrer geänderten Bestellung zu entsprechen. – Thomas

0

ich es herausgefunden, wie CASE Wort Flucht zu vermeiden.

Sie können $ _reserved_identifiers Variable innerhalb CI_DB_driver Klasse ändern. Wenn Sie die gesamte Datei nicht ändern möchten, können Sie sie einfach in Ihrer Model-Klasse vor dieser Abfrage ändern.

$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); 

(ich weiß nicht, ob es auf 3.x Zweig arbeiten wird. Es funktioniert auf 2.x Zweig gut)

0

er eine gute Lösung in another answer on SO so im Fall gefunden Sie gelandet Diese Seite habe ich nicht gefunden und werde sie hier erneut veröffentlichen.


Sie können eine Case-Anweisung verwenden, wenn Sie die Case-Anweisung in Klammern wickeln.

$this->db->order_by(" 
    (CASE p.submit_to 
     WHEN '' THEN 0 
     WHEN 'writer' THEN 1 
     ELSE 2 
    END), 
    p.request_end_date asc" 
); 
0

Ich habe heute getestet und es funktioniert.

Sie können es verwenden, wie Sie sagten, immer wenn Sie den zweiten Parameter FALSE verwenden, um das Escaping zu deaktivieren.

$this->db->order_by("CASE p.submit_to 
            WHEN '' THEN 0 
            WHEN 'writer' THEN 1 
            ELSE 2 
           END, p.request_end_date asc",FALSE); 

Grüße.