2016-12-31 94 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; 
相關問題