我的目标是使用MySQL计算两个日期之间的年、月和天数,而无需定义函数/存储过程。期望的输出将是"0";12y 5m 3d";(十二年零五个月零三天(。
我研究过多篇早期的帖子,我很接近,但很难找到";天";组成部分
到目前为止,我有:
SET @ReferenceDate = '1988-06-04';
SELECT CONCAT ( FLOOR( (TIMESTAMPDIFF(MONTH, @ReferenceDate, CURDATE()) / 12) ), 'y ',
MOD( TIMESTAMPDIFF(MONTH, @ReferenceDate, CURDATE()) , 12) , 'm ',
/* not sure what function to use for the remaining "days" portion */ 'd '
) AS Duration;
我相信我可以使用DATEDIFF(date1,date2(来获取日期数,但我很难配置正确的第二个参数,因此它只计算最后一个部分月份的天数(而不是自开始以来的天数(。
如能就这一点提供任何指导,我们将不胜感激。非常感谢。
您遇到的问题是,您可以将任何一天作为参考依据,而您运行的日期可以是其他任何一天。例如:以本月19日为基准,但今天是4日。你需要做的是将NOW日期恢复到基准日期的多少天,这样基准日期现在就有效了。
因此,参考日期(只是与第4个不同,第4个与当前日期相同(
参考日期="1988-06-18"(6月18日(。所以,如果我们把这个日期放回本月1日,我们就减去了17天。现在,不管今天是什么,都要把它带回来17天,这样它就会被当天的轮班所抵消。9月4日到8月18日是17天。现在,您有一个与今天相同日期偏移的月1日日期关联。所以你的天数现在是18天。你的年和月计算看起来不错。
通过根据每月1天(@ReferenceDate(执行DATE_ADD((,您可以到达本月的第一天。例如:18日成为1-18的日期加成=负17,因此回滚17天。
以下是此类输出的示例。
select
FLOOR( (TIMESTAMPDIFF(MONTH, subset.baseDate, subset.DateShift) / 12) ) difYears,
MOD( TIMESTAMPDIFF(MONTH, subset.baseDate, subset.DateShift) , 12) difMonths,
DAYOFMONTH( subset.DateShift ) difDays
from
( select
dayofmonth( @ReferenceDate ) -1 as daysOffset,
date_add( @ReferenceDate, INTERVAL 1-dayofmonth( @ReferenceDate ) DAY ) as baseDate,
date_add( curdate(), INTERVAL 1-dayofmonth( @ReferenceDate ) DAY ) as DateShift
from
( select @ReferenceDate := '1988-06-08' ) sqlvars ) subset
如果您试图提取某些给定条件的所有记录,只需将内部查询更改为类似的内容
select
subset.*,
FLOOR( (TIMESTAMPDIFF(MONTH, subset.baseDate, subset.DateShift) / 12) ) difYears,
MOD( TIMESTAMPDIFF(MONTH, subset.baseDate, subset.DateShift) , 12) difMonths,
DAYOFMONTH( subset.DateShift ) difDays
from
( select
dayofmonth( yt.SomeDateColumn ) -1 as daysOffset,
date_add( yt.SomeDateColumn, INTERVAL 1-dayofmonth( yt.SomeDateColumn ) DAY ) as baseDate,
date_add( curdate(), INTERVAL 1-dayofmonth( yt.SomeDateColumn ) DAY ) as DateShift,
yt.OtherColumnsYouMayWant
from
YourTable yt
where
yt.SomeColumnCondition = 'whatever' ) subset
因此,现在,您可以在预查询中获得许多记录,其中每个记录都有各自的参考日期基础,计算出相应的日期偏移量,并将当前日期偏移所述日期。然后从结果中抽出你的年/月/天。
主要基于这个答案,并考虑到@ReferenceDate
可能在未来(因此使用ABS()
(:
SET @ReferenceDate = '1988-06-04';
SELECT
CONCAT(
ABS(DATE_FORMAT( CURDATE(), '%Y' ) - DATE_FORMAT( @ReferenceDate, '%Y' )), 'y',
ABS(DATE_FORMAT( CURDATE(), '%m' ) - DATE_FORMAT( @ReferenceDate, '%m' )), 'm',
ABS(DATE_FORMAT( CURDATE(), '%d' ) - DATE_FORMAT( @ReferenceDate, '%d' )), 'd'
) AS Duration