Я проверил это со следующими данными:
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`