codeigniter select 记录日期范围内的记录而不重复记录

codeigniter select records from date range without repeating a record

我正在处理一个需要以下查询但无法完成的项目。

数据库:evenstdb

--------------------------------------
| Event_id | startDate |    endDate  |
--------------------------------------
|82637     |01-02-2020 |  02-03-2020 |
--------------------------------------
|66363     |10-03-2020 |  31-11-2020 |
--------------------------------------

我有一个页面,我应该根据选定的日期范围列出事件。一切正常,但问题是有时我会两次列出相同的事件,因为我同时根据 startDateendDate 列出事件。有时开始日期和结束日期在选定的日期范围内。我怎样才能只显示一次事件?

我的代码:

// $date1 and $date2 are date inputs from the form 

$query = $this->db->where('startDate >=', $date1);
$query = $this->db->where('startDate <=', $date2);
$query = $this->db->get('evenstdb');
$results1 =  $query->result();

$query = $this->db->where('endDate >=', $date1);
$query = $this->db->where('endDate <=', $date2);
$query = $this->db->get('evenstdb');
$results2 =  $query->result();

$data["eventsList"] = array_merge($results1,$results2);

如果每条记录要同时匹配两个日期范围,您可以尝试通过一个包含所有 4 个条件的查询来获取所需的记录:

$this->db->where('startDate >=', $date1)
         ->where('startDate <=', $date2)
         ->where('endDate >=', $date1)
         ->where('endDate <=', $date2);

$result = $this->db->get('evenstdb')->result();

如果每条记录至少匹配一个日期范围,你也可以尝试通过一次查询获取所需的记录,但将条件分为两部分连接 OR(如果这两个中的任何一个都将返回记录组 returns true):

$this->db->group_start()
             ->where('startDate >=', $date1)
             ->where('startDate <=', $date2)
                 ->or_group_start()
                     ->where('endDate >=', $date1)
                     ->where('endDate <=', $date2)
                 ->group_end()
         ->group_end();

$result = $this->db->get('evenstdb')->result();

我最近需要一个查询来查找 MySQL 中重叠的日期范围。此解决方案比上面的日期范围解决方案执行得更好,并且工作完美。

你也可以这样做:

AND DATEDIFF(LEAST($date2, endDate),GREATEST($date1, startDate)) > 0;

link 的示例查询:

SELECT o.orderStart, o.orderEnd, s.startDate, s.endDate
, GREATEST(LEAST(orderEnd, endDate) - GREATEST(orderStart, startDate), 0)>0 as overlaps
, DATEDIFF(LEAST(orderEnd, endDate), GREATEST(orderStart, startDate)) as overlap_length
FROM orders o
JOIN dates s USING (customerId)
WHERE 1
AND DATEDIFF(LEAST(orderEnd, endDate),GREATEST(orderStart, startDate)) > 0;