首页 文章

MYSQL如何在MYSQL中执行两个日期之间的自定义月份差异?

提问于
浏览
-3

我的要求是在2个日期之间分别计算总月数,然后分别计算破损月份(即表格中的第一个日期和第二个日期是当前日期) . 如果破损的月份总数超过15,则将其视为一个月的经验,如果其低于15,则不将其视为1个月的经验 .

假设我在桌上的日期为25/11/2018,当前日期是06/01/2019;中间整整一个月是12月,所以1个月的经验;破损的月份是11月和1月,所以现在我必须计算11月的6天和1月的6天的日期,所以12天,<=(lte)15,所以总经验将四舍五入到1个月的经验

我在stackoverflow中提到了与计算MYSQL中的日期差异有关的多个问题,但找不到任何可能的选项 . MYSQL TIMESTAMPDIFF,TIMEDIFF,PERIOD_DIFF,DATE_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到日期(10-12-2018)的经验是12个月= 13个月 . 由于13岁在9岁到24岁之间,Sam的记录是预期的输出之一 .

1 回答

  • 0

    我认为这个查询会做你想要的 . 它用

    (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
    

    我们可以将此表达式用作 userallowed_exp_range 之间的 JOIN 条件,以查找在给定范围内具有经验的所有用户:

    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
    

    我创建了一个小的demo on dbfiddle,它演示了到达结果的步骤 .

相关问题