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方式,具体可参考