如何查询显示不同月份的数据?

How to query to display data that has different months?

所以,我有一个视图报告显示,它过滤了 Period From 和 Period To,如下所示:

而且,我有日期如下的员工数据:

然后,当我查看报表时,2 月的 end_date 没有出现,因为期间从和到进程仅在 1 月。它应该出现,因为 start_date 在一月份。

这是我的查询,请帮忙。

$this->db->select("a.id, a.employee_id, a.employee_name, a.leave_name, a.start_date, a.end_date, a.status, 
                   b.id, b.employee_id, b.job_title_name, b.employment_status_name")
         ->join('hr_employee b', 'a.employee_id = b.employee_id', 'left')
         ->where("a.start_date AND a.end_date BETWEEN '$data[from]' AND '$data[to]'");

   return $this->db->get('hr_leaves a');

解决方案 1: 如果有效,请使用此查询:

->where("('$data[from]' BETWEEN a.start_date AND a.end_date) OR ('$data['to']' BETWEEN a.start_date AND a.end_date");

方案二: 创建一个日期间隔并查询员工开始日期和结束日期之间的每个日期,如果为真,则添加到列表 $sql_res.

    $begin = new DateTime($data['from']);
    $end = new DateTime($data['to']);
    
    $interval = DateInterval::createFromDateString('1 day');
    $period = new DatePeriod($begin, $interval, $end);
    
    $sql_res = array();
    foreach ($period as $dt) {
        $curent_date = $dt->format("Y-m-d");
        $this->db->select("a.id, a.employee_id, a.employee_name, a.leave_name, a.start_date, a.end_date, a.status, 
                   b.id, b.employee_id, b.job_title_name, b.employment_status_name")
         ->join('hr_employee b', 'a.employee_id = b.employee_id', 'left')
         ->where("$curent_date BETWEEN a.start_date AND a.end_date");

         $sql_res[] = $this->db->get('hr_leaves a')->row();
    }

    return $sql_res;

开始日期确实在两个日期参数之间,但是您没有过滤开始日期,只过滤结束日期!您只需要从开始日期起就将其设置为非零值。

由于结束日期不在参数指定的日期范围内,高亮行被过滤掉

你应该

  1. 仅过滤开始日期 ("a.start_date BETWEEN '$data[from]' AND '$data[to]') 或
  2. 过滤开始日期和结束日期,但使用 or 运算符,否则将不会返回突出显示的行 ("(a.start_date BETWEEN '$data[from]' AND $data[to]) OR (a.end_date BETWEEN '$data[from]' AND '$data[to]'))。

另请注意,您应该使用参数而不是字符串插值来在查询中包含 from 和 to 参数。

如果您希望期间过滤器查找日期范围完全重叠的任何员工数据,您需要:

where least(a.end_date, <period-end-date>) >= greatest(a.start_date, <period-start-date>)

检查“重叠”时间范围:

"a.start_date AND a.end_date BETWEEN '$data[from]' AND '$data[to]'"

我推荐它简洁明了,虽然有点神秘:

"a.start_date <= '$data[to]'  AND   -- eg, hire_date <= '2022-01-31'
 a.end_date   >= '$data[from]'      -- eg, quit_date >= '2022-01-01'