mysql如何在mysql中自定义两个日期之间的月差?

ukdjmx9f  于 2021-06-18  发布在  Mysql
关注(0)|答案(1)|浏览(393)

我的要求是分别计算两个日期之间的总月数和中断月数(即表中的第一个日期和第二个日期是当前日期)。如果中断月总数大于15,则将其计为一个月经验,如果小于15,则不将其计为一个月经验。
假设我在表上的日期是2018年11月25日,当前日期是2019年1月6日;中间的一个月是十二月,所以有一个月的经验;中断的月份是11月和1月,所以现在我要计算的日期是11月的6天和1月的6天,所以12天和<=(lte)15,所以总经验将四舍五入到1个月的经验
我从stackoverflow中引用了多个与计算mysql中的日期差有关的问题,但是找不到任何可能的选项。mysql timestampdiff、timediff、period\u diff、date\u diff中的内置函数没有给出我所需的结果,因为它们的计算方法与我的计算要求不同。
任何关于如何在mysql中执行此计算并将其结果作为sql语句的一部分的线索都将对我有所帮助。在同一个sql中,一旦该值到达,就会验证该值是否在给定的值范围内。
包括样表结构和值:

table_name = "user"

id | name | join_date 
---------------------
1| Sam | 25-11-2017
2| Moe | 03-04-2017
3| Tim | 04-07-2018
4| Sal | 30-01-2017
5| Joe | 13-08-2018

我想从上表中找出用户,他们的经验是基于上述逻辑以月为单位计算的。如果这些月份介于以下两个范围之间,则将获取这些用户以进行进一步处理。

table_name: "allowed_exp_range"
starting_exp_months | end_exp_months
-------------------------------------
0 | 6
9 | 24

例如:根据我的计算,sam到2018年12月10日的经验是12+1个月=13个月。因为13是在9到24之间,山姆的记录是预期的输出之一。

pxq42qpu

pxq42qpu1#

我想这个查询可以满足你的要求。它使用

(YEAR(CURDATE())*12+MONTH(CURDATE()))
- (YEAR(STR_TO_DATE(join_date, '%d-%m-%Y'))*12+MONTH(STR_TO_DATE(join_date, '%d-%m-%Y'))) -
- 1

要获得用户的整个月体验数,

DAY(LAST_DAY(STR_TO_DATE(join_date, '%d-%m-%Y')))
- DAY(STR_TO_DATE(join_date, '%d-%m-%Y'))
+ 1

得到第一个月的天数,以及

DAY(CURDATE())

获取当前月份的天数。两天的计数相加,如果总数大于15,则在整月数上加1,例如。

SELECT id
     , name
     , (YEAR(CURDATE())*12+MONTH(CURDATE())) - (YEAR(STR_TO_DATE(join_date, '%d-%m-%Y'))*12+MONTH(STR_TO_DATE(join_date, '%d-%m-%Y'))) - 1 -- whole months
       + CASE WHEN DAY(LAST_DAY(STR_TO_DATE(join_date, '%d-%m-%Y'))) - DAY(STR_TO_DATE(join_date, '%d-%m-%Y')) + 1 + DAY(CURDATE()) > 15 THEN 1 ELSE 0 END -- broken month
       AS months
FROM user

我们可以用这个表达式作为 JOIN 条件介于 user 以及 allowed_exp_range 要查找在给定范围内有经验的所有用户,请执行以下操作:

SELECT u.id
     , u.name
     , a.starting_exp_months
     , a.end_exp_months
FROM user u
JOIN allowed_exp_range a
ON (YEAR(CURDATE())*12+MONTH(CURDATE())) - (YEAR(STR_TO_DATE(u.join_date, '%d-%m-%Y'))*12+MONTH(STR_TO_DATE(u.join_date, '%d-%m-%Y'))) - 1
       + CASE WHEN DAY(LAST_DAY(STR_TO_DATE(u.join_date, '%d-%m-%Y'))) - DAY(STR_TO_DATE(u.join_date, '%d-%m-%Y')) + 1 + DAY(CURDATE()) > 15 THEN 1 ELSE 0 END
       BETWEEN a.starting_exp_months AND a.end_exp_months

输出(对于示例数据,包括所有用户,因为他们都适合某个体验范围):

id  name    starting_exp_months     end_exp_months
1   Sam     9                       24
2   Moe     9                       24
3   Tim     0                       6
4   Sal     9                       24
5   Joe     0                       6

我在dbfiddle上创建了一个小演示,演示了获得结果的步骤。

相关问题