CI 數據庫使用積累php
1、 or_like使用sql
情景:WMS庫存列表過濾器經過產品名稱或者SKU查詢。數據庫
一般此狀況採用CI框架提供的or_like語句,如數組
$this->db->like(Product_model::TABLENAME . '.' .'product_name', value);框架 $this->db->or_like(Product_model::TABLENAME.'.'.'origin_sku', value);函數 |
但此狀況若是在有用$this->db->where的時候會出現問題。如新增codeigniter
$this->db->where(Product_model::TABLENAME . '.' .'cate_id', $value);this |
實際呈現出來的sql語句是相似spa
Where 'product_name' like %value% or 'origin_sku' like %value% and 'cate_id' = valuecode |
但咱們實際想要的結果是以下
Where ('product_name' like %value% or 'origin_sku' like %value%) and 'cate_id' = value |
兩者之間區別就是少了一對括號,所查詢的結果集則不同。
若是查詢的結果集是經過上述包含括號的SQL查詢語句獲得的,則能夠經過修改CI框架。查找到DB_active_rec.php文件中的_compile_select函數實現,修改以下:
// Write the "LIKE" portion of the query if (count($this->ar_like) > 0) { if (count($this->ar_where) > 0) { $sql .= "\nAND ("; }
$sql .= implode("\n", $this->ar_like);
if (count($this->ar_where) > 0) { $sql .= ")"; } }
|
但修改此框架會致使原有功能缺失。有的用戶但願獲得查詢的結果集就剛恰好是沒有包含括號的SQL語句,則又得回滾代碼。
故咱們另外採用的一種方式是經過CI 框架的where語句結合sql查詢語句方式。以下:
$left = "'%"; $right = "%'"; $sql = '(' . Product_model::TABLENAME . '.' . 'product_name like ' . $left . $value . $right . ' or ' . Product_model::TABLENAME . '.' . 'origin_sku like ' . $left . $value . $right . ')'; $this->db->where($sql, null, false); |
Where語句採用CI框架提供的第四種方式:自定義字符串方式,但注意的是where語句傳參在CI框架用戶指南上是有誤的,使用方式應是$this->db->where($sql, null, false)。
2、 distinct使用
情景:經過過濾器查詢產品名稱來獲取售後申請信息。售後申請信息是單獨的數據表tbl_sales_order,而相應的售後申請信息所包含的產品信息則是在tbl_sales_order_products,但tbl_sales_order_product則只包含產品ID,也就是product_id,具體的產品名稱需經過product_id查詢tbl_products來獲取。若是要經過查詢產品名稱來獲取售後申請則須要聯合售後申請信息表、售後產品表以及產品名稱表。
一般採用的語句以下:
$this->db->from(self::TABLENAME); $this->db->join(Sales_order_products_model::TABLENAME,self::TABLENAME . '.' . 'id' . '=' . Sales_order_products_model::TABLENAME . '.' . 'sale_order_id'); $this->db->join(Product_model::TABLENAME,Sales_order_products_model::TABLENAME . '.' . 'product_id' . '=' . Product_model::TABLENAME . '.' . 'id'); if(!is_null($per_page)){ $this->db->limit($per_page, $page*$per_page); } $this->db->select(self::TABLENAME . '.' . '*'); |
上述狀況在一張售後申請表對應一條產品信息的時候是可行的,但若是有一張售後申請有多條產品信息的時候,會出現多條冗餘的售後申請信息,故需去掉冗餘的信息,可採用CI框架提供的函數distinct。
$this->db->distinct(); |
3、 union使用
情景:WMS系統中要呈現一張退貨單報表,包含售後退貨以及拒收/未妥投訂單信息。其中包含售後退貨和拒收/未妥投兩種業務,兩者之中只存在部分字段可複用,此報表只提供經過起始時間和截止時間查詢結果。這意味着在輸出結果集是須要合併表單數據,可經過union字段。
正常的一種使用方式是獲取兩個結果集進行合併輸出。以下例子:
// Query #1 $this->db->select('title, content, date'); $this->db->from('mytable1'); $query1 = $this->db->get()->result(); // Query #2 $this->db->select('title, content, date'); $this->db->from('mytable2'); $query2 = $this->db->get()->result(); // Merge both query results $query = array_merge($query1, $query2);
|
但此方式在進行分頁顯示須要自行對數組進行處理。
第二種方式是採用網上提供的一種方式,調用_compile_select和_reset_select接口。以下:
$this->db->select('title, content, date'); $this->db->from('mytable'); $query = $this->db->get(); $subQuery1 = $this->db->_compile_select(); $this->db->_reset_select(); // #2 SubQueries no.2 ------------------------------------------- $this->db->select('title, content, date'); $this->db->from('mytable2'); $query = $this->db->get(); $subQuery2 = $this->db->_compile_select(); $this->db->_reset_select(); // #3 Union with Simple Manual Queries -------------------------- $this->db->query("select * from ($subQuery1 UNION $subQuery2) as unionTable"); // #3 (alternative) Union with another Active Record ------------ $this->db->from("($subQuery1 UNION $subQuery2)"); $this->db->get();
|
但此方式實際使用是會報錯,_compile_select和_reset_select接口是保護性的,沒法調用。
第三種方式則是採用CI框架提供的last_query接口,獲取上述查詢語句(注:不是查詢結果),而後再經過query接口合併SQL語句進行查詢,實際WMS採用的就是此方式,實際用例以下:
public function get_return_by_condition($condition=array(), $page,$per_page='10'){ $this->db->select(array('tbl_sales_order.id as id', 'order_id', 'create_date')); $this->db->from('tbl_sales_order'); $this->db->join('tbl_sales_operate_log', 'tbl_sales_order.id = tbl_sales_operate_log.sale_order_id'); $this->db->where('tbl_sales_order.product_status', 7); $this->db->where('tbl_sales_order.payment_status', 135); $this->db->where('tbl_sales_operate_log.product_status', 7); $this->db->where('tbl_sales_operate_log.payment_status', 135); $this->db->distinct(); //return $query2 = $this->db->get()->result(); $query = $this->db->get(); $subQuery1 = $this->db->last_query();
$this->db->from('tbl_purchase_order'); $this->db->join('tbl_order_stockout', 'tbl_purchase_order.id = tbl_order_stockout.order_purchase_id'); $this->db->join('tbl_order_action', 'tbl_order_action.order_id = tbl_order_stockout.order_id'); $this->db->where('tbl_order_action.mark', 1); //1表示訂單狀態 $this->db->where('tbl_order_action.action_status', '123'); //訂單取消爲123 $this->db->distinct(); $this->db->select(array('tbl_purchase_order.id as id', 'tbl_purchase_order.create_date as create_date', 'tbl_order_stockout.order_id as order_id', )); //return $this->db->get()->result(); $query = $this->db->get(); $subQuery2 = $this->db->last_query(); $sql = 'select * from ($subQuery1 UNION $subQuery2) as unionTable'; if(!is_null($per_page)){ $sql .= 'limit ' . $per_page * $page . ', ' . $per_page; } return $this->db->query($sql)->result(); } |
第四種方式採用從新CI框架,支持UNION方式,具體可參考