You need to enable JavaScript to run this app. CodeIgniter查询构造器关联逗号分隔字段实现技能费用统计
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter查询构造器关联逗号分隔字段实现技能费用统计

问题根因定位
  • 核心查询逻辑缺陷:查询Schedule表时调用row('Do_skill'),仅能返回时间范围内匹配的第一条排班记录的技能列表,所有后续排班记录中的技能会被完全遗漏,自然无法匹配到对应价格,累加结果远低于预期。
  • 字符串清洗缺失:逗号分隔转数组的方法未对拆分后的技能名做trim去空格处理,例如排班字段中"Engineering, Freelancer"拆分出的带前置空格的" Freelancer",无法和skillqmount表中无空格的标准技能名Freelancer匹配,导致对应价格漏算。
  • 数值计算失效:skillqmount表的Price字段存储为带$符号、空格的字符串(如$ 5),直接调用select_sum('price')会因为字段为字符串类型无法正确累加数值,结果不符合预期。
  • 边界匹配遗漏:原代码对结束日期使用<比较,会漏掉日期恰好等于结束日期的排班记录、价格记录,和业务预期的“选定时间段内”的统计范围不匹配。
修正后的完整实现

首先替换Check_model中的字符串处理方法:

public function comma_separated_to_array($chck, $separator = ','){
    if (empty($chck)) {
        return [];
    }
    $raw_vals = explode($separator, $chck);
    $clean_vals = [];
    foreach ($raw_vals as $val) {
        // 去除前后多余空格,过滤空值
        $trimmed_val = trim($val);
        if ($trimmed_val !== '') {
            $clean_vals[] = $trimmed_val;
        }
    }
    // 单条排班内的技能去重,减少冗余匹配
    return array_unique($clean_vals);
}

再替换控制器端的业务逻辑:

<?php
$startd = $this->input->post('A');
$endd = $this->input->post('B');

// 步骤1:收集选定时间段内所有排班记录的关联技能
$schedule_res = $this->db
    ->select('Do_skill')
    ->where('Activ_date >=', $startd)
    ->where('Activ_date <=', $endd) // 根据业务调整边界,如需排除当天可改回<
    ->get('Schedule');

$matched_skills = [];
if ($schedule_res->num_rows() > 0) {
    foreach ($schedule_res->result() as $schedule_row) {
        $row_skills = $this->Check_model->comma_separated_to_array($schedule_row->Do_skill);
        $matched_skills = array_merge($matched_skills, $row_skills);
    }
    // 全局技能去重,避免where_in冗余
    $matched_skills = array_unique($matched_skills);
}

// 无匹配技能时直接返回0
if (empty($matched_skills)) {
    echo '$0';
    exit;
}

// 步骤2:清洗价格字段后做累加统计,匹配时间段内对应技能的价格
$total_amount = $this->db
    // 把带$、空格的字符串价格转为数值再求和
    ->select_sum("CAST(REPLACE(REPLACE(price, '$', ''), ' ', '') AS DECIMAL(10,2))", 'total_price')
    ->where('Date_skill >=', $startd)
    ->where('Date_skill <=', $endd)
    ->where_in('Skill', $matched_skills)
    ->get('skillqmount')
    ->row('total_price');

// 格式化输出结果
echo '$' . number_format((float)$total_amount, 2);
实现说明
  • 全量技能收集:不再仅取第一条排班的技能,而是遍历时间范围内所有排班记录,把所有关联技能汇总去重后再做匹配,解决原逻辑漏算技能的问题。
  • 技能名标准化:拆分逗号字符串时同步去除前后空格,保证和skillqmount表的标准技能名格式完全一致,避免格式不匹配导致的漏算。
  • 价格字段清洗:通过SQL内的REPLACE、CAST操作把字符串类型的带符号价格转为纯数值类型,再执行求和,解决字符串无法累加的问题。
  • 边界可配置:根据业务实际统计范围调整日期比较的运算符,示例中使用<=保证结束日期当天的记录被纳入统计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 22:57:03