使用下表結構:
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