我的日期范围从当月的 30th 固定到下个月的 10th 。
我在PHP中使用PHP。在PHP中,我对数组进行了硬编码:
$dates = array(30,31,1,2,3,4,5,6,7,8,9,10);
因此,在建立与数据库的连接之前,如果日期属于任何此范围,我已经过滤,如果是,则允许,如果不允许,则不允许。
但是,在MySQL中,我应该使用哪些数据库表设计和查询来执行要求:
可能的情况是:
答案 0 :(得分:2)
使用以下表格结构:
CREATE TABLE `monthly` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`action_date` date DEFAULT NULL,
`period` char(6) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `period` (`period`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
其中action_date将是您在MySQL日期格式中的实际日期(即YYYY-MM-DD
),而句点将是YYYYMM
格式标识符,它将在您定义的日期范围内的每一天具有相同的值。
使用此表达式计算给定日期的期间值:
select (
case
when (day('2016-01-30') mod 30) > 10 then null
when (day('2016-01-30') div 30) = 1 then concat(year('2016-01-30'), lpad(month('2016-01-30'), 2, 0))
else concat(year('2016-01-30' - interval 1 month), lpad(month('2016-01-30' - interval 1 month), 2, 0))
end)
as period;
使用' 2016-12-30'在上面将产生' 201612',使用' 2017-01-07'也将使用' 2017-01-12'产生' 201612'将产生null。由于期间列为unique
和not null
,因此您无法插入超出定义范围的值,并且您只能为每个插入一个值你的范围。
使用以下语句将新值插入表中(当然将日期值替换为实际日期):
insert into monthly (action_date, period)
values (
'2017-01-30',
case
when (day('2017-01-30') mod 30) > 10 then null
when (day('2017-01-30') div 30) = 1 then concat(year('2017-01-30'), lpad(month('2017-01-30'), 2, 0))
else concat(year('2017-01-30' - interval 1 month), lpad(month('22017-01-30' - interval 1 month), 2, 0))
end
)
作为旁注:从第30天到下个月第10天的固定日期范围似乎很奇怪 - 您是否在设计中考虑二月,只有28天或29天?
编辑:实际上,使用date_format而不是连接年份和月份值,它更简单,更清洁:
select (
case
when (day('2016-01-30') mod 30) > 10 then null
when (day('2016-01-30') div 30) = 1 then date_format('2016-01-30', '%Y%m')
else date_format(('2016-01-30' - interval 1 month), '%Y%m')
end)
as period;