我有两个表(虽然它们可以合并为一个):一个有周期指示符(0 =年,1 =月),另一个包含开始日期。一个时期可以是一个月或一年,我需要找出当前时期。
表A:
id type
7 1
269 1
270 1
271 0
表B:
id start end
7 24-11-2013 31-12-2099
9 24-11-2013 31-12-2099
10 28-11-2013 28-11-2014
271 20-12-2013 31-12-2099
现在我需要找到表B中每个id的当前时间段开始的日期。例如:
我能实现这只是纯MySQL吗?
编辑:请注意我在日期中使用了DD-MM-YYYY表示法。如果这令人困惑,我道歉答案 0 :(得分:2)
有趣的案例。我们可以使用条件语句,根据当前日期和开始日期之间的关系采取不同的操作。
set @when = "2015-03-01";
select b.start,
b.end,
case when type = 1 then
case
when day(@when) < day(b.start) then
b.start + interval abs(
period_diff(
concat(
year(b.start),
lpad(month(b.start), 2, "0")
),
concat(
year(@when),
lpad(month(@when), 2, "0")
)
)) -1 month
when day(@when) >= day(b.start) then
b.start + interval abs(
period_diff(
concat(
year(b.start),
lpad(month(b.start), 2, "0")
),
concat(
year(@when),
lpad(month(@when), 2, "0")
)
)) month
end
when type = 0 then
b.start + interval (year(@when) - YEAR(b.start) - (date_format(@when, '%m%d') < DATE_FORMAT(b.start, '%m%d'))) year
end current_period_start
from tableb b
inner join tablea a
on b.id = a.id;
它应该正确处理像闰年这样的事情,2月的天数比其他月份少。等等。在这种情况下,我使用变量来保存当前日期,只是为了帮助测试那些不同的场景。您只需将@when
替换为查询中的now()
,即可与当前日期进行比较。
period_diff
是一个计算两个日期之间月份差异的函数,但它的愚蠢之处在于它不会采用实际的日期参数,而是一个字符串形式的字符串&#39; YYYYMM&#39;
无论如何,就查询而言,如果type = 1
,它会找到两个日期之间的月份差异,并将其添加到开始日期以获取最近的月度周年纪念日。它还会检查当月的日期,以查看周年纪念日在当前月份或之前的月份是否下降,如果是前一次,则从计算的差异中减去1,因为period_diff
是愚蠢的,并且没有。考虑到日子。
年份计算更简单,只需返回年份差异,然后减去1或0,具体取决于我们的月份和日期是否小于起始月份和日期。
有一个演示here