【问题标题】:How to check if a date is a specific day in the week in MySQL?如何检查日期是否是 MySQL 中一周中的特定日期?
【发布时间】:2021-12-18 14:28:28
【问题描述】:

我有一个 MySQL 表 presence,其结构如下:

  • id:1
  • uid:14
  • 开始:2021-11-01 00:00:00
  • 结束:2021-12-31 00:00:00
  • 重复:1

这一行给我的信息是,用户 14 从 2021 年 11 月 1 日到 2021 年 12 月 31 日每周一都在场。

SELECT 1
FROM presences
WHERE 2021-11-15 BETWEEN DATE(`start`) AND DATE(`end`)

检查给定日期 (2021-11-15) 是否在他的出席日期之间,但是如何添加逻辑来检查“每个星期一”?此外,如果end 为空,它应该在未来的每个星期一检查,没有结束。 星期一由start 日期给出,也可以是每隔一天。 repetitive 让我检查start 给定的日期。如果repetitive 为0,它应该像我的查询一样检查,如果日期在startend 之间。

人工查询:从presence 表中获取所有行,其中给定日期在开始和结束之间(如果 end 不为空)并且给定日期是开始日期。

【问题讨论】:

  • weekday(start) = 0 检查星期一

标签: mysql date datetime weekday


【解决方案1】:

直接回答您帖子标题中提出的问题,您可以使用:

  • DAYOFWEEK(date):返回日期的工作日索引(1 = 星期日,2 = 星期一,...,7 = 星期六)。这些索引值符合 ODBC 标准。

  • WEEKDAY(date):返回日期的工作日索引(0 = 星期一,1 = 星期二,... 6 = 星期日)。

  • DAYNAME(date):返回日期的工作日名称。用于名称的语言由 lc_time_names 系统变量的值控制

但是在你想要的查询的描述中,你说

如果 end 不为 null 并且 给定日期是开始日期,则从存在中获取给定日期在开始和结束之间的所有行。 (我的重点)

这意味着您想要start 日期日期名称/索引的实例数在您的范围内。为此,您可以使用不同的方法将范围外推到行并从中选择所需的日期。

日历表是最好的,因为您已经可以在表中的数据中构建日期名称/索引。

SELECT COUNT(*) as monday_count
FROM presences JOIN calendar
  ON calendar.day_date BETWEEN DATE(`start`) AND DATE(`end`)
WHERE `end` IS NOT NULL AND calendar.day_name = DAYNAME(`start`);

这是一个example of building a calendar table,它是特定于 MSSQL 的,因此可能需要针对 MySQL 修改一些查询,但你明白了。

【讨论】:

    【解决方案2】:

    从存在中获取给定日期在开始和结束之间的所有行, 如果 end 不为 null 并且给定的日期是开始日。

    可以人工翻译为:

    SELECT *
    FROM t
    WHERE '2021-11-15' >= `start`
    AND (
        '2021-11-15' <= `end` OR
        `end` IS NULL
    )
    AND (
        repetitive = 0 OR
        repetitive = 1 AND WEEKDAY('2021-11-15') = WEEKDAY(`start`)
    )
    

    【讨论】:

    • 我非常喜欢OR end IS NULL。我想念的是,当repetitive0 时,它应该只检查给定日期是否在startend 之间。如果是1,您的查询将起作用
    • 这与我要找的很接近。唯一缺少的是,end 可以是 NOT NULL,但重复可以是 1。比它应该每天检查 start 和 end 之间。
    • 不能再编辑了。所以:如果给定了 start 和 end,查询必须在 start 和 end 之间进行检查。如果 end 为 null,则查询必须从开始检查直到无穷大。如果重复为 1,请检查工作日。 if 0 每天检查。
    • 我认为它正是这样做的。我将重新排列括号以使其清楚。
    • 我只是在 startend 周围添加 date() 以真正忽略时间,如果给定的日期是完整的时间戳
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    相关资源
    最近更新 更多