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

CI模型查询考勤数据出现Subquery returns more than 1 row错误如何解决

问题原因
  • 两次触发Subquery returns more than 1 row错误的核心是:你写在SELECT后的标量子查询没有绑定外层查询的user_id和tanggal字段,子查询会匹配全表所有符合keterangan='Masuk'/keterangan='Pulang'的记录,返回多条数据,不符合标量子查询只能返回单值的要求。
  • 首次编写的代码关联条件用了OR会导致匹配范围溢出,且没有给内层和外层的表加别名区分,字段匹配逻辑混乱。
解决方案

完全可以从单表获取按日期聚合的上下班打卡数据,推荐使用条件聚合方案,性能比嵌套子查询更高,逻辑更清晰,CodeIgniter中实现代码如下:

public function get_absen($id_user, $bulan, $tahun)
{
    // 用CASE WHEN做条件聚合,匹配同日期同用户的上下班时间
    $this->db->select("
        DATE_FORMAT(tanggal, '%d-%m-%Y') AS tanggal,
        MAX(CASE WHEN keterangan = 'Masuk' THEN waktu END) AS jam_masuk,
        MAX(CASE WHEN keterangan = 'Pulang' THEN waktu END) AS jam_pulang
    ");
    $this->db->where('user_id', $id_user);
    $this->db->where("DATE_FORMAT(tanggal, '%m') = ", $bulan);
    $this->db->where("DATE_FORMAT(tanggal, '%Y') = ", $tahun);
    // 可选:需要过滤有效打卡类型可加这个条件,不需要可以删除
    $this->db->where_in('keterangan', ['Masuk', 'Pulang']);
    $this->db->group_by("DATE_FORMAT(tanggal, '%d-%m-%Y')");
    $result = $this->db->get('attendance');
    return $result->result_array();
}

代码说明

用CASE WHEN按打卡类型筛选对应时间,配合聚合函数MAX取到对应类型的打卡值,同一天如果有多次同类型打卡,会取最晚的那次,你也可以根据需求换成MIN取最早的打卡时间。如果需要严格和clocks表的配置对齐,可以保留keterangan IN (SELECT keterangan FROM clocks)的过滤条件。

如果你一定要用子查询的写法实现,需要给子查询加上外层关联条件,修正后的写法如下:

public function get_absen($id_user, $bulan, $tahun)
{
    $this->db->select("
        DATE_FORMAT(a.tanggal, '%d-%m-%Y') AS tanggal,
        (SELECT waktu FROM attendance b 
         WHERE b.keterangan = 'Masuk' 
         AND b.user_id = a.user_id 
         AND DATE(b.tanggal) = DATE(a.tanggal)
         LIMIT 1) AS jam_masuk,
        (SELECT waktu FROM attendance c 
         WHERE c.keterangan = 'Pulang' 
         AND c.user_id = a.user_id 
         AND DATE(c.tanggal) = DATE(a.tanggal)
         LIMIT 1) AS jam_pulang
    ");
    $this->db->from('attendance a');
    $this->db->where('a.user_id', $id_user);
    $this->db->where("DATE_FORMAT(a.tanggal, '%m') = ", $bulan);
    $this->db->where("DATE_FORMAT(a.tanggal, '%Y') = ", $tahun);
    $this->db->group_by("DATE(a.tanggal)");
    $result = $this->db->get();
    return $result->result_array();
}

这里给内层子查询加了LIMIT 1确保只返回单值,同时关联了外层的用户ID和日期,避免匹配到无关记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:36:06