使用下表结构:
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;
使用在“二〇一六年十二月三十日”以上将产生“201612”,用“2017年1月7日”将也产生'201612',使用'2017-01-12'将产生无效。由于期间列是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;
使日期字段唯一 –
'什么数据库表设计和查询我应该使用以下要求“,这不属于SO。您可以通过dba.stackexchange.com询问 – Jigar
INSERT ... SELECT类型的查询就足够了。有关更多帮助,请参阅http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very-simple- sql-query – Strawberry