2016-12-31 178 views
2

我有一个日期范围固定从30日本月到第10日下个月。如何检查日期是否在指定的日期范围内

我使用PHP和MySQL。在PHP我硬编码数组:

$dates = array(30,31,1,2,3,4,5,6,7,8,9,10); 

因此已向数据库的连接之前,我已经如果日期落在任何的这个范围,如果是,允许的,如果没有,不允许过滤。

然而,在MySQL哪些数据库表设计和查询我应该使用以下要求

  1. 用户提起诉讼来插入数据,如果系统在上述日期范围之间没有记录允许插入否则禁止。
  2. 用户可以在任何时间点按下按钮执行操作,因此我需要检查当时是否有任何记录(或许检查是最难的部分)。

可能出现的情况是:

  1. 鉴于当前日期是31-DEC-2016(有效的,因为日期范围),用户尝试插入的数据,并在数据库中没有任何数据,因此成功地插入。
  2. 第二天,01-DEC-2016用户尝试再次插入,但系统检测到在当前日期的日期范围内已经存在的记录落入(01-DEC-2016落在范围31-DEC-2016 〜10-JAN-2017)如何查询这种情况?
+1

使日期字段唯一 –

+0

'什么数据库表设计和查询我应该使用以下要求“,这不属于SO。您可以通过dba.stackexchange.com询问 – Jigar

+0

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

回答

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; 

使用在“二〇一六年十二月三十日”以上将产生“201612”,用“2017年1月7日”将也产生'201612',使用'2017-01-12'将产生无效。由于期间列是uniquenot 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; 
相关问题