You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter 3.1.5中or_where_in与其他where条件的正确用法咨询

解决CodeIgniter 3.1.5中or_where_in与其他条件配合的逻辑错误问题

我来帮你排查这个问题,核心原因是逻辑运算符的优先级导致的,咱们一步步说清楚:

问题根源

当你直接使用or_where_in时,它会和后面的日期where条件形成OR逻辑关系,最终生成的SQL大概是这样的:

SELECT * FROM bills 
WHERE type = ? 
AND user_id = ? 
OR user_id IN (?, ?, ...) 
AND DATE(created_at) BETWEEN 'xxx' AND 'xxx'

因为SQL中AND的优先级高于OR,这就会导致只要满足user_id IN (...)的记录,不管日期是否在范围内都会被返回——这就是你看到“返回未选中日期结果”的原因。而改用where_in时,可能是因为没有同时满足user_id = $user_id和user_id IN $get_all_user_ids的记录,所以无数据返回。

正确的写法:用分组包裹OR条件

CodeIgniter提供了group_start()和group_end()方法来帮你把一组条件用括号包裹,确保逻辑符合预期。修改后的代码如下:

public function get_date_wise_sales_info($start_date, $end_date,$type=NULL,$user_id=NULL,$get_all_user_ids=NULL) {
    if(!empty($type)) {
        $this->db->where('type',$type);
    }

    // 把用户ID的相关条件分组,确保OR只在这组内生效
    if(!empty($user_id) || !empty($get_all_user_ids)) {
        $this->db->group_start(); // 生成左括号
        if(!empty($user_id)) {
            $this->db->where('user_id', $user_id);
        }
        if(!empty($get_all_user_ids)) {
            $this->db->or_where_in('user_id',$get_all_user_ids);
        }
        $this->db->group_end(); // 生成右括号
    }

    // 建议用参数绑定避免SQL注入风险
    $this->db->where("DATE(bills.created_at) BETWEEN ? AND ?", array($start_date, $end_date));
    
    $this->db->order_by('bills.id','desc');
    $query = $this->db->get('bills');
    return $query->result();
}

为什么这样有效?

修改后生成的SQL会变成:

SELECT * FROM bills 
WHERE type = ? 
AND (user_id = ? OR user_id IN (?, ?, ...)) 
AND DATE(created_at) BETWEEN 'xxx' AND 'xxx'

括号把用户ID的两个条件包裹成一个整体,和其他条件都是AND关系,这样就保证了:

  • 必须满足日期范围
  • 同时满足type条件(如果有)
  • 同时满足“指定user_id”或者“user_id在数组中”的其中一个条件

另外补充个小提示:直接把日期变量拼到SQL里存在SQL注入风险,我上面改成了参数绑定的写法,这是更安全的做法哦。

内容的提问来源于stack exchange,提问作者user_777

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:45:21