我的表中有一列叫做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
請不要標記您的標題。 –