繁体   English   中英

如何在 MySQL 中处理当月的闰年

[英]How to handle Leap Years in anniversary for a current month in MySQL

我正在尝试编写一个查询来查找用户当月的工作周年纪念日并考虑闰年(不知道如何在查询中管理)

表“ emp_detail ”:

emp_no 加入日期
1 2002-06-10
2 2022-06-25
3 2020-02-29
4 2002-02-15
5 2011-02-01

到目前为止,我已经尝试了以下查询:

SELECT no,
       join_date
       CASE WHEN DATEADD(YY,DATEDIFF(yy,join_date,GETDATE()),join_date) < GETDATE() 
            THEN DATEDIFF(yy,join_date,GETDATE())
            ELSE DATEDIFF(yy,join_date,GETDATE()) - 1 
       END AS 'anniversary'
FROM emp_detail
WHERE 'status' = 'active' 
HAVING MONTH(join_date) = 06/07/08 -- ...so on

编辑:预期 output:

2022 年 2 月

emp_no 加入日期 周年纪念日
3 2020-02-29 2022-02-28(在这里,想要获得 2020 年 2 月 29 日的闰年记录和非闰年 2022)
4 2002-02-15 2022-02-15
5 2011-02-01 2022-02-01

考虑到闰年,正在寻找一种方法来显示员工的周年纪念日在本月初。

我是否朝着正确的方向前进? 任何帮助都会很棒。

您可以将问题分为两个步骤:

  • 使用当前月份过滤您的“ join_date ”值
  • 将年份更改为您的“ join_date
  • 获取更新的“ join_date ”和该日期的最后一天之间的最小值(>>这将有效地处理闰年而不是其他尝试每次检查特定年份的解决方案)
WITH cte AS (
    SELECT emp_no,
           join_date,
           STR_TO_DATE(CONCAT_WS('-',
                                 YEAR (CURRENT_DATE()),
                                 MONTH(join_date     ),
                                 DAY  (join_date     )),
                       '%Y-%m-%d') AS join_date_now
    FROM tab 
    WHERE MONTH(join_date) = MONTH(CURRENT_DATE())
      AND YEAR(join_date)  < YEAR(CURRENT_DATE())
)
SELECT emp_no,
       join_date,
       LEAST(join_date_now, LAST_DAY(join_date_now)) AS anniversary_date
FROM cte

这里查看演示

注意:在演示中,由于您想查看 2 月份的月份而我们是 7 月份,因此WHERE子句在检查月份时将包含一个额外的 -5。

大多数(全部?)SQL 引擎已经按照您想要的方式处理涉及闰日的年份算术:将闰日折叠到二月的最后一天。

因此,计算员工的join_date + INTERVAL x YEAR将正确处理'2020-02-29' 要计算当前年份在 MySQL/MariaDB 中的时间间隔,您可以 使用 TIMESTAMPDIFF 自己计算 EXTRACTed 年份之间的差异:

SELECT emp_no,
       join_date,
       join_date +
         INTERVAL (EXTRACT(YEAR FROM CURDATE()) -
                   EXTRACT(YEAR FROM join_date)) YEAR
         AS "anniversary_date_this_year",
       ....

您可以在 MySQL 中使用extract function

select * from emp_detail where extract( month from (select now())) = extract( month from join_date)  and extract( year from (select now())) != extract( year from join_date);

上述查询将显示当月工作周年纪念日的所有员工。
对于下表:
在此处输入图像描述
上面的查询将显示以下行。
在此处输入图像描述

以下查询还考虑闰年。

  1. 如果员工在闰年的 2 月 29 日加入并且当前年份是非闰年,则查询将周年日期显示为“currentYear-Feb-28”

  2. 如果员工在闰年的 2 月 29 日加入,并且当年也是闰年,则查询显示 Anniversay Date 为“currentYear-Feb-29”

     select empId, case when ( ( extract(year from (select now()))%4 = 0 and extract(year from (select now()))%100,= 0 ) or extract(year from (select now())) % 400 = 0 ) then cast( concat( extract(year from (select now())), '-', extract( month from join_date),'-', extract( day from join_date) ) as date) when ( ( (extract(year from join_date) % 4 = 0 and extract(year from join_date)%100,= 0) or extract( year from join_date)%400 = 0) and extract(month from join_date) =2 and extract(day from join_date) = 29 ) then cast( concat( cast( extract(year from (select now())) as nchar), '-02-28') as date) else cast( concat( extract(year from (select now())), '-', extract( month from join_date);'-' extract( day from join_date) ) as date) end as AnniversaryDate from emp_detail where extract(year from join_date) = extract(year from (select now()))

Emp_detail 数据在此处输入图像描述

对于此数据,查询将显示以下行在此处输入图像描述

此外,如果您只想将日期过滤到当前月份,您可以使用extract function。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM