根据加入日期计算员工的下一个3周年纪念日

时间:2016-09-15 22:40:37

标签: mysql sql

我有一个员工mysql数据库表,其中包含员工姓名和开始日期。我希望能够计算从今天起每个员工即将到来的3周年纪念日。 (例如,乔丹的下一个即将到来的周年纪念日将是08/25/2019,李的将是09/22/2017,迈克的10/26/2018)

id    name       startDate        
---------------------------
0     Jordan     08/25/2010          
1     Lee        09/22/2014          
2     Mike       10/26/2015        

低效的强力解决方案是生成从startDate到当前日期的所有周年日期加上今天的日期之后的一个日期,然后选择它。

但必须有一个更高效的SQL查询,以根据今天的日期显示每位员工的下一个即将到来的周年纪念日。必须以某种方式使用DATEDIFF。

3 个答案:

答案 0 :(得分:1)

EDITED

SELECT
  *
  ,CASE
    WHEN CURDATE() <= startDate THEN startDate + INTERVAL 3 year
    WHEN MOD((YEAR(CURDATE()) - YEAR(startDate)),3) = 0
      AND (CURDATE() - INTERVAL YEAR(CURDATE()) year) 
          <= (startDate - INTERVAL YEAR(startDate) year) 
      THEN startDate + INTERVAL (YEAR(CURDATE()) - YEAR(startDate)) year
    ELSE startDate + INTERVAL (year(CURDATE()) - YEAR(startDate) + 3 - MOD(YEAR(CURDATE()) - YEAR(startDate),3)) year
  END   as "Next3YrAniversary"
FROM
  TableName

SQL小提示向您展示它使用测试用例: http://www.sqlfiddle.com/#!9/cf276a/1

无论如何,这个想法如下:

  • startDate is Today or in future if so just add 3 years
  • Remainder of (Yesrs Diff / 3) = 0 and if current month/day is <= month/day of startDate如果这样的周年纪念今年还没有发生,那么add number of years between current date and startDate to startDate。如果它是2016并且周年纪念日在2016,那么它会以稍微不同的方式说明它是否会在今年发生周年纪念日。
  • 否则添加到开始日期:Number of years between Start Date & Now + 3 years - Remainder of (Years between Now and startDate / 3)

关于YEAR() vs year的说明。你可以写year()YEAR()我倾向于大写我的特定功能等,但是year()函数只能获得日期年份的INT。所以YEAR(CURDATE())表示获取当前日期的年份,例如2016YEAR(startDate)获得startDate的年份,例如2013MOD()为您提供分组的余数2 / 3 remainder 1

2016 - 2013 gives you 3 so remainder of 3/3 is 0

小写年份不是函数[没有括号]定义了可以使用日,年,月等的INTERVAL类型。

date INTERVAL + 1 year = add 1 year to date

另一个例子是

startDate INTERVAL + NumOfYearsDiff year = add NumOfYearsDiff to startDate

在案例2中,比较我所做的是将两个日期基本上YEAR 0001减去日期中的年份整数,然后比较哪个日期将告诉我哪个日期是一年中的晚些时候才能理解周年纪念日已经过去或今年仍在上升。 TIMESTAMPDIFF会在一定程度上为您自动执行此操作,但如果您使用,那么周年纪念日将是下一个,例如2019如果今天在2016。因此,如果您想要将其显示为今天,您仍然必须检查我所做的相同条件,这意味着没有真正的理由使用TIMESTAMPDIFF

这是我方法,斯宾塞和戈登的并排比较 http://www.sqlfiddle.com/#!9/cf276a/3

它显示的内容:

  • 如果周年纪念日是今天戈登的&amp;斯宾塞的方法将显示下一个周年纪念,即今天+ 3年。哪种可能或不可取?
  • Gordon对未来日期的回答将显示startDate而不是startDate + 3年

答案 1 :(得分:0)

嗯,我认为这有点麻烦,但你可以在一个声明中做到这一点。

我认为可行的逻辑是在数年内取得差异,并将近似为3年。然后将其添加到开始日期。如果这大于当前日期,那就是下一个开始日期。否则,再增加三年:

12/31/2017

答案 2 :(得分:0)

戈登回答的方法很好。我只是认为需要稍作修改。使用:

INTERVAL 0 +代替INTERVAL 3 +

并使用

INTERVAL 3 +代替INTERVAL 6 +

我不想惹恼戈登的回答。

以下是完全相同方法的演示,语法稍有不同,并且还会在将来添加对startdate的检查,我们希望在startdate添加3年(至得到第一个三周年纪念日。)

SELECT t.id
     , t.name
     , t.startdate
     , CASE
       WHEN t.startdate > DATE(NOW())
       THEN t.startdate + INTERVAL 3 YEAR
       WHEN t.startdate + INTERVAL FLOOR( TIMESTAMPDIFF(YEAR,t.startdate,NOW()) /3)*3 YEAR > DATE(NOW())
       THEN t.startdate + INTERVAL FLOOR( TIMESTAMPDIFF(YEAR,t.startdate,NOW()) /3)*3 YEAR
       ELSE t.startdate + INTERVAL FLOOR( TIMESTAMPDIFF(YEAR,t.startdate,NOW()) /3)*3 + 3 YEAR
       END AS next_3yr_anniv
  FROM mytable t
 ORDER BY ...