我的表中有一列叫做expiry_date
。我使用下面的查询返回此日期,加上6个月:我该如何做这个日期计算?
SELECT DATE_ADD(expiry_date, INTERVAL 6 MONTH) AS expiry_date;
我想修改上面的,这样如果expiry_date
加6个月过去(CURRENT_DATE
之前),另外6个月根据需要添加多次,直到日期为止。
我该如何使用MySQL来做到这一点?
我的表中有一列叫做expiry_date
。我使用下面的查询返回此日期,加上6个月:我该如何做这个日期计算?
SELECT DATE_ADD(expiry_date, INTERVAL 6 MONTH) AS expiry_date;
我想修改上面的,这样如果expiry_date
加6个月过去(CURRENT_DATE
之前),另外6个月根据需要添加多次,直到日期为止。
我该如何使用MySQL来做到这一点?
第一种方法:
SELECT
case when expiry_date > SYSDATE() then
DATE_ADD( expiry_date , INTERVAL 6 MONTH)
else
DATE_ADD(
DATE_SUB(
SYSDATE(),
INTERVAL
(DATEDIFF(SYSDATE(), expiry_date) % (6 * 30))
MONTH
)
,
INTERVAL 6 MONTH)
end
AS expiry_date
FROM ...
未经测试。
这里的30天值是否与计算的INTERVAL值一样准确? (我不知道差别 - 要求清楚。) – MyStream
不,这个答案其实是错误的。根据日期的不同,增加5,6或7个月。 –
我用下面的数据来测试这一点:
Table: `test`
uid expiry_date
1 2011-11-03
2 2011-01-20
代码:
SELECT
`uid`,
`expiry_date`,
PERIOD_DIFF(
date_format(DATE_ADD(CURDATE(),INTERVAL 1 DAY),'%Y%m'),
date_format(`expiry_date`,'%Y%m')
) as `dif`, /* Straight Month Difference */
CEIL(PERIOD_DIFF(
date_format(DATE_ADD(CURDATE(),INTERVAL 1 DAY),'%Y%m'),
date_format(`expiry_date`,'%Y%m')
)/6) AS `dif2`, /* How many blocks of 6 months, rounded up */
(
IF(
(/* If 1 block is > today, add the 6 months and finish */
DATE_ADD(
CURDATE(),
INTERVAL 1 DAY
) < DATE_ADD(
`tOuter`.`expiry_date`,
INTERVAL 6 MONTH
)
), /* this is with just 6 months added */
DATE_ADD(
`tOuter`.`expiry_date`,
INTERVAL 6 MONTH
), /* this works out how many blocks of 6 months to add */
DATE_ADD(
`tOuter`.`expiry_date`,
INTERVAL (
6 * CEIL(/* round up number of months */
PERIOD_DIFF(/* get number of months */
date_format(
DATE_ADD(
CURDATE(),
INTERVAL 1 DAY
),
'%Y%m'
),
date_format(
`expiry_date`,
'%Y%m'
)
)/6 /* divide months by 6 to match question */
)
) MONTH /* add the dynamically calculated interval */
)
)
) AS `expiry_date_calculated` FROM `test` AS `tOuter`
它导致:
uid expiry_date dif dif2 expired_date_calculated
1 2011-11-03 0 0 2012-05-03
2 3011-01-20 10 2 2012-01-20
这是此输入所需的输出?
性能备注:这在性能上很糟糕,我邀请其他人建议更高效的例程。这可能会更好地写成一个存储过程,并且如果您将CURDATE()的日期作为字符串传递,那么它肯定会更好。
示例:使用2个字段,需要0.04秒来产生上述所需的结果。
编辑:较小的版本:
SELECT
`id`, `expiry_date`,
(IF((DATE_ADD(CURDATE(),INTERVAL 1 DAY) < DATE_ADD(`expiry_date`,INTERVAL 6 MONTH)),
DATE_ADD(`expiry_date`,INTERVAL 6 MONTH),
DATE_ADD(`expiry_date`,
INTERVAL (6 * CEIL(PERIOD_DIFF(
date_format(DATE_ADD(CURDATE(),INTERVAL 1 DAY),'%Y%m'),
date_format(`expiry_date`,'%Y%m')
)/6)) MONTH
)
)
) AS `expiry_date_calculated`
您应该添加任何X年6个月或X年和12个月你EXPIRY_DATE。 X是他们今年的部分现在()和expiry_date之间的差异。
select if(dayofyear(expiry_date)>=dayofyear(now()),
date_add(test, interval concat(year(now())-year(expiry_date), '-6') year_month),
date_add(test, interval concat(year(now())-year(expiry_date), '-12') year_month))
as expiry_date from <table>;
一个例子。 EXPIRY_DATE是2009-10-01
DAYOFYEAR(EXPIRY_DATE)是274
DAYOFYEAR(现在的())是325
所以第一个条件是假的。 concat(year(now())-year(expiry_date), '-12'
给出2011-2009 = 2年和12个月(字符串是'2-12'),并且用于date_add('2009-10-01', interval '2-12' year_month
即2011-10-01 + 6个月= 2012-05-01。
'expiry_date'是什么格式? – MyStream
@MyStream:这是'DATE'字段 – gjb
请不要标记您的标题。 –