我有一个MySQL表presence
,其结构如下:
- id:1
- uid:14
- 开始时间:2021-11-01 00:00:00
- 结束时间:2021-12-31 00:00:00
- 重复:1
此行为我提供了信息,即用户14在2021-11-01至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,那么它应该像我的查询一样进行检查,如果日期在start
和end
之间。
人工查询:从presence
表中获取给定日期介于开始和结束之间(如果结束不为空(以及给定日期为开始日期的所有行。
从存在中获取给定日期介于开始和结束之间的所有行,如果结束不为空,并且给定的日期是开始的日期。
可以人工翻译为:
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`)
)
直接回答帖子标题中提出的问题可以使用:
-
DAYOFWEEK(date(:返回日期的工作日索引(1=周日,2=周一,…,7=周六(。这些索引值对应于ODBC标准。
-
WEEKDAY(date(:返回日期的工作日索引(0=周一,1=周二,…6=周日(。
-
DAYNAME(date(:返回日期的工作日名称。用于名称的语言由lc_time_names系统变量的值控制
但在您想要的查询描述中,您说
如果end不为null,则从presence中获取给定日期介于开始和结束之间的所有行,并且如果给定日期为开始日期则从present中获取所有行。(我的重点(
这意味着您希望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`);
这里有一个构建日历表的例子,它是MSSQL特定的,所以可能需要为MySQL修改一些查询,但你已经明白了。