如何在列表中显示当月日期在新的月份中当月日期在A和B之间的列表中的当月项目

时间:2019-01-02 12:38:28

标签: mysql sql

去年我建立了一个项目管理系统,但是现在正值新的一年,我被(我)的一些新手编码所困扰:)

因此,现在我真的需要您的帮助来了解如何一劳永逸地解决此问题。

错误:

当前的主要问题是在年度结转中,现在我的SQL查询无法理解新年的月份(1)大于当前的年份(12),因此该年度没有显示列表中正确的项目。

有什么想法吗?预先感谢!

这是我当前的SQL查询:

SELECT *
FROM projects
WHERE MONTH(CURDATE()) between MONTH(project_start) and MONTH(project_delivery)
AND YEAR(CURDATE()) between YEAR(project_start) and YEAR(project_delivery)
order by project_id

这是表项目的原始结构:

Project_id projet_start projet_delivery
1          2018-12-20   2018-12-22
2          2018-12-25   2018-12-29
3          2018-12-28   2018-12-28
4          2018-12-30   2019-01-22

2 个答案:

答案 0 :(得分:1)

BETWEEN适用于实际日期:

SELECT *
FROM projects
WHERE CURDATE() between project_start and project_delivery
order by project_id

如果您想要从月(月粒度)开始的所有事情,而不是日粒度:

SELECT *
FROM projects
WHERE CURDATE() between DATE_SUB(project_start, INTERVAL DAY(project_start)-1 DAY) and 
  DATE_ADD(DATE_SUB(project_delivery, INTERVAL DAY(project_delivery) DAY), INTERVAL 1 MONTH)
order by project_id

因此,如果一个项目在12月5日开始并在1月19日完成,那么这将提供12月1日至1月31日之间的所有内容。不过请记住,如果1月31日的任何日期也有时间成分(即晚于午夜),则表示该日期早于此结束日期,并且不会显示。

如果是这种情况,并希望获得帮助来解决它(最简单的方法是不要使用BETWEEN,因为它的两端总是包含在内,请使用<,这是专有的)

更新:本月有活动的项目,即:

  • 开始于,结束于
  • 开始于,之后结束
  • 开始于,结束于
  • 开始于,结束于

所有这些共同点是,项目的开始日期在本月底之前,并且项目的结束日期在本月初

SELECT *
FROM projects
WHERE 
  --started before the end of this month
  project_start < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL DAY(CURDATE()) - 1 DAY), INTERVAL 1 MONTH) AND
  --ended after the start of this month
  project_delivery > DATE_SUB(CURDATE(), INTERVAL DAY(CURDATE()) DAY) 

order by project_id

进行DATE_SUB(CURDATE(), INTERVAL DAY(CURDATE()) DAY)是写“从当前日期减去当前天数”即2019-01-02 minus 2 -> 2018-12-31的一种相当复杂的方法。我们为此寻找日期>(以免包含日期)

类似地,DATE_ADD(DATE_SUB(CURDATE(), INTERVAL DAY(CURDATE()) - 1 DAY), INTERVAL 1 MONTH)减去当前日期DAY-1(所以这次只有1个,而不是2个)就可以到达本月1日,然后加上一个月即可到达下个月的第一天。 2019-01-02 -> 2019-01-01 -> 2019-02-01。再次<,因此是独家

如果您在例如1月31日,并且先添加一个月,则存在另一种错误(添加一个月,然后在子日)的错误-没有2月31日,因此mysql将在28日的上限2月,然后减去31天,给出的日期不是1月底(即1月28日)

答案 1 :(得分:0)

仅使用日期比较:

select p.*
from projects p
where curdate() >= project_start and
      curdate() <= project_delivery;

我不确定您为什么要将日期分为时间部分。但是,完全没有必要进行比较。

如果您只想在月份级别进行比较,那么一种方法是将值转换为月份:

select p.*
from projects p
where year(curdate()) * 12 + month(curdate()) >=  year(project_start) * 12 + month(project_start) and
      year(curdate()) * 12 + month(curdate()) <= year(project_delivery) * 12 + month(project_delivery);

或者,将日期移动到月初:

select p.*
from projects p
where curdate() >= project_start + interval 1 - day(project_start) day and
      curdate() < ( project_delivery + interval (1 - day(project_delivery) day) + interval 1 month;