【问题标题】:Is a date within some of periods [closed]是某些时期内的日期[关闭]
【发布时间】:2019-04-23 12:02:02
【问题描述】:

我有下面的项目表及其活动期间(期间用 FROM 和 TO 日期定义):

ID | ProjID | ActiveFrom | ActiveTo
===+========+============+============
 1 |     20 | 2018-01-01 | 2018-01-20
 2 |     20 | 2018-02-05 | 2018-02-12
 3 |     20 | 2018-02-20 | 2018-02-27
 4 |     30 | 2018-01-15 | 2018-02-15

当然,一个项目可以有任意数量的活动期。

我需要一个 SQL 查询(函数),如果给定项目在某个给定日期(在某些项目活动期间内的给定日期)处于活动状态,它将返回 true/false。

【问题讨论】:

  • 太棒了!那么到目前为止你有tried anything 吗?
  • 提示:WHERE 和一些日期比较。
  • 是的,我尝试了一些方法,但我遇到了任意数量的周期的问题。如果知道周期数,那么就很容易了,但是如何在未知的周期数内进行检查。
  • 提示:SELECT CASE COUNT(*) WHEN > 0 THEN TRUE ELSE FALSE FROM project WHERE '2018-11-21' BETWEEN(ActiveFrom, ActiveTo)
  • 感谢@AntonyGibbs,这是一个很好的提示:SELECT COUNT(*) FROM projects WHERE projId=20 AND '2018-01-21' BETWEEN ActiveFrom AND ActiveTo

标签: mysql sql


【解决方案1】:

这个函数应该做你想做的事。它依赖于 MySQL 在数字上下文中将布尔结果视为 1 或 0,因此 MAX 调用实际上成为所有条件中的 OR

CREATE FUNCTION check_activity(project_id INT, check_date DATE)
RETURNS BOOLEAN
DETERMINISTIC
BEGIN
  RETURN (SELECT MAX(check_date BETWEEN ActiveFrom AND ActiveTo) FROM projects WHERE ProjId = project_id);
END
SELECT check_activity(20, '2018-01-10'), check_activity(20, '2018-02-01')

输出

check_activity(20, '2018-01-10')    check_activity(20, '2018-02-01')
1                                   0

Demo on dbfiddle

【讨论】:

  • 就是这样,我不习惯在 SELECT 中使用 BETWEEN 作为逻辑测试(我一直在 WHERE 子句中使用它)。伙计们对我的问题进行了负面标记,尽管它并不像看起来那么简单。
  • @sbrbot 同意,未知的周期数确实使它更复杂。 MySQL 将布尔值视为整数这一事实使得可以提出一个相对简单的解决方案,而不必遍历所有句点。请注意,由于它最终是单行的,因此您可能不需要将其包含在函数中。
  • 没错,如果请求的日期至少在一个周期内(如果没有重叠,则只有一个 1,但未指定非重叠周期),@Nick 在这里使用 MAX 返回 1。此外,我想避免在函数中循环遍历句点,这就是为什么我更改了需要查询(然后是函数)。但是,我认为人们低估了这个问题。
猜你喜欢
  • 2019-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多