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

如何在CodeIgniter中结合日期范围与SUM聚合函数实现左连接

问题分析与解决方案

你遇到的核心问题是左连接后被WHERE条件过滤成了内连接,同时GROUP BY的字段选择也有问题,导致无法获取到没有支出记录的分类。咱们一步步来修正:

问题根源

  1. WHERE子句过滤了左连接的空值:当某个分类在expenses表中没有对应记录时,e.expenses_date会是NULL,而你的BETWEEN条件会直接排除这些NULL的行,相当于把左连接变成了内连接。
  2. GROUP BY字段错误:你用e.expenses_category来分组,没有匹配记录的分类这个字段是NULL,会被合并到同一组,而且无法关联到左表的分类信息。

修正后的代码

把日期条件移到JOIN的ON子句中,同时GROUP BY左表的分类字段:

$this->db->select('ec.expensescategory_name, ec.budget, COALESCE(SUM(e.expenses_amount), 0) as amount')
         ->from('expensescategory ec')
         ->join('expenses e', 'ec.expensescategory_id = e.expenses_category 
                              AND e.expenses_date BETWEEN "' . date('Y-m-d', strtotime($start)) . '" 
                              AND "' . date('Y-m-d', strtotime($end)) . '"', 'left')
         ->group_by('ec.expensescategory_id, ec.expensescategory_name, ec.budget');
$query = $this->db->get();
return $query->result_array();

关键调整说明

  • 将日期条件放到JOIN的ON里:这样只会在关联expenses表时筛选符合日期范围的记录,不会过滤掉左表中没有匹配的分类行。
  • 用COALESCE处理SUM的空值:如果某个分类没有支出记录,SUM(e.expenses_amount)会返回NULL,用COALESCE把它转换成0,更符合预算对比的需求。
  • GROUP BY左表的字段:确保每个分类(即使没有支出)都能单独成组,而不是被合并到空值组里。

另外,为了避免SQL注入风险,建议用CodeIgniter的参数绑定来处理日期变量,比如:

$startDate = date('Y-m-d', strtotime($start));
$endDate = date('Y-m-d', strtotime($end));

$this->db->select('ec.expensescategory_name, ec.budget, COALESCE(SUM(e.expenses_amount), 0) as amount')
         ->from('expensescategory ec')
         ->join('expenses e', 'ec.expensescategory_id = e.expenses_category 
                              AND e.expenses_date BETWEEN ? AND ?', 'left', false)
         ->bind_param('ss', $startDate, $endDate)
         ->group_by('ec.expensescategory_id, ec.expensescategory_name, ec.budget');

这样能更安全地处理用户输入的日期参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 08:42:31