我在 2 个搜索日期之间检索事件的查询没有返回任何结果,为啥?

Posted

技术标签:

【中文标题】我在 2 个搜索日期之间检索事件的查询没有返回任何结果,为啥?【英文标题】:My query to retrieve events between 2 search dates does not return any results, why?我在 2 个搜索日期之间检索事件的查询没有返回任何结果,为什么? 【发布时间】:2021-02-01 21:39:31 【问题描述】:

上下文

我已经用表格建模了一个日历。条目是日历的事件:

id ; event_start_date ; event_end_date.

一个条目是:

11 ; 2021-01-28 15:15:37 ; 2022-01-11 15:15:37

我编写的脚本接受日期的搜索间隔作为条目,并应返回搜索间隔内包含的所有事件(如果搜索间隔包含在事件间隔中,或者如果搜索间隔日期之一包含在事件间隔中,或者如果事件间隔包含在搜索间隔中)。 我认为不应该返回结果的(唯一)情况是:如果搜索间隔完全超出所有事件的范围。

搜索、预期和实际行为示例

考虑以下搜索间隔:search_start_date = 2021-01-26 00:00:00search_end_date = 2021-01-30 00:00:00

预期行为:应该返回事件 #11,因为即使 search_start_date 超出了事件的间隔,search_end_date 也在其中。

实际行为:不返回任何事件。

脚本

使用的 SGBD:mysql。使用的语言:SQL。

select *, @search_start_date:="2021-01-26 00:00:00", @search_end_date:="2021-01-30 00:00:00" 

from `calendars_events` 

where

(@search_start_date between `event_start_date` and `event_end_date`) or (@search_end_date between `event_start_date` and `event_end_date`)

or

(`event_start_date` between @search_start_date and @search_end_date) or (`event_end_date` between @search_start_date and @search_end_date)

问题

为什么没有返回事件?我认为我正确使用了 MySQL 变量,并且我认为我可以使用 between 进行日期比较。

【问题讨论】:

令人困惑...为什么没有event_start_date 或类似的`?你怎么知道活动什么时候开始?为什么搜索会混合搜索记录的创建时间戳和事件的时间段? event_start_dateevent_creation_date :-) 好的,然后命名不好...... @stickybit 是的,我真的很抱歉先生,我已经编辑了问题^^' 重叠测试很简单。如果事件 A 在事件 B 结束之前开始,并且在事件 B 开始之后结束,则事件 A 与事件 B 重叠。 【参考方案1】:

变量必须在FROM子句(MySQL query / clause execution order)中初始化,条件可以简单很多:

SELECT e.* 
FROM `calendars_events` e, (
  SELECT
    @search_start_date:="2021-01-26 00:00:00",
    @search_end_date:="2021-01-30 00:00:00"
  ) vars
WHERE @search_start_date <= event_end_date AND @search_end_date >= event_start_date

fiddle

请注意,从 MySQL 8 开始在表达式中设置用户变量已被弃用,并将在未来的版本中删除。

【讨论】:

【参考方案2】:

MySQL 不清楚何时初始化变量。我很确定,如果它们在 FROM 子句中初始化,那么在其他子句之前对其进行评估。所以,我会推荐:

select ce.*, @search_creation_date, @search_end_date
from calendars_events ce cross join
     (select @search_creation_date := '2021-01-26', @search_end_date := '2021-01-30' 
where (@search_creation_date between `event_creation_date` and `event_end_date`) or
      (@search_end_date between `event_creation_date` and `event_end_date`) or
      (`event_creation_date` between @search_creation_date and @search_end_date) or (`event_end_date` between @search_creation_date and @search_end_date);

您还可以在select 之前在语句中分配变量。

注意:我不确定您的 where 子句是否真的符合您的要求。但是你没有描述。您可能想问另一个关于如何确定两个时间段是否重叠的问题。

您也可以将其作为两个语句运行:

select @search_creation_date := '2021-01-26', @search_end_date := '2021-01-30' ;

select ce.*, @search_creation_date, @search_end_date
from calendars_events ce 
where . . .;

【讨论】:

> "您还可以在 select 之前的语句中分配变量。" - 你什么意思?

以上是关于我在 2 个搜索日期之间检索事件的查询没有返回任何结果,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 查询从表中检索数据和第二个查询以提取其他结果,没有重复

如何在没有一年的情况下检索从 Google 通讯录同步的联系人事件?

C# - 在不同日期的 2 个 DateTime 对象之间搜索时间

3个日期范围之间的Mysql查询

在没有的查询的返回中插入日期

在日期范围之间使用 TOPCOUNT 的 MDX 查询返回带有一些空值的顶部