2011-04-30 38 views
4

我們正在創建世界歷史數據庫的歷史歸檔,我們需要一個引用AD中所有日期的日期查找表。如何創建此表格的值 - 從1AD到2011年爲YYYY/MM/DD?數據庫是MySQL。AD日期的數據倉庫

問題:

  1. 我用Excel預填充的日期,然後導入到MySQL作爲:YYYY/MM/DD但Excel不能識別幾年如0007 0008等等等等我無法自動複製單元格來生成日期。我必須手動做到這一點,這需要幾天時間,從1AD到2011年爲YYYY/MM/DD。

  2. 閏年是在1752年引入的。如果我以編程方式生成日期,如何處理1752年之前沒有閏年的日期?它會產生錯誤的日​​期。

我的表:

CREATE TABLE `dates` (
     `date_id` int(10) NOT NULL, 
     `format` char(10) NOT NULL, 
     `century` int(10) NOT NULL, 
     `decade` int(10) NOT NULL, 
     `year` int(10) NOT NULL, 
     `month` int(10) NOT NULL, 
     `week` int(10) NOT NULL, 
     `day` int(10) NOT NULL, 
     `month_year` int(10) NOT NULL, 
     `week_year` int(10) NOT NULL, 
     `week_month` int(10) NOT NULL, 
     `day_year` int(10) NOT NULL, 
     `day_month` int(10) NOT NULL, 
     `day_week` int(10) NOT NULL, 
     PRIMARY KEY (`date_id`) 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
+1

爲什麼普通的'datetime'型列不足?是否有具有多個日期或日期範圍的事件? – 2011-04-30 20:18:46

+0

是的,這是一個深入分析世界歷史數據庫。想想任何像世界大戰,革命等事件都會跨越數天,數週,數月,數年等等。另外,我們有歷史的信仰,就像人們相信直到19-20世紀的女巫一樣,這個信念跨越了數千年年份。 – yardy 2011-04-30 20:25:23

+1

即使是日期範圍,你只需要兩個'datetime'列(開始/結束)......你的方法仍然讓我感到有趣。你能證明爲什麼'datetime'列不夠?關於這個最糟糕的部分是,你每天都需要在'日期'表中創建一個新記錄......至少在9999AD的時間裏,你將不得不生成日期。而最糟糕的是,這張表中的大部分將會充滿重複數據(例如,世紀通常是無用的 - 您可以在運行時確定這一點,不需要數據庫行告訴你這一點)。 – 2011-04-30 20:33:57

回答

7

使用這樣的SQL(用我自己的表結構,而不是一個你雖然有):

DROP TABLE IF EXISTS time_dimension; 
CREATE TABLE time_dimension (
     id      INTEGER PRIMARY KEY, -- year*10000+month*100+day 
     db_date     DATE NOT NULL, 
     year     INTEGER NOT NULL, 
     month     INTEGER NOT NULL, -- 1 to 12 
     day      INTEGER NOT NULL, -- 1 to 31 
     quarter     INTEGER NOT NULL, -- 1 to 4 
     week     INTEGER NOT NULL, -- 1 to 52/53 
     day_name    VARCHAR(9) NOT NULL, -- 'Monday', 'Tuesday'... 
     month_name    VARCHAR(9) NOT NULL, -- 'January', 'February'... 
     holiday_flag   CHAR(1) DEFAULT 'f' CHECK (holiday_flag in ('t', 'f')), 
     weekend_flag   CHAR(1) DEFAULT 'f' CHECK (weekday_flag in ('t', 'f')), 
     event     VARCHAR(50), 
     UNIQUE td_ymd_idx (year,month,day), 
     UNIQUE td_dbdate_idx (db_date) 

) Engine=MyISAM; 

DROP PROCEDURE IF EXISTS fill_date_dimension; 
DELIMITER // 
CREATE PROCEDURE fill_date_dimension(IN startdate DATE,IN stopdate DATE) 
BEGIN 
    DECLARE currentdate DATE; 
    SET currentdate = startdate; 
    WHILE currentdate < stopdate DO 
     INSERT INTO time_dimension VALUES (
         YEAR(currentdate)*10000+MONTH(currentdate)*100 + DAY(currentdate), 
         currentdate, 
         YEAR(currentdate), 
         MONTH(currentdate), 
         DAY(currentdate), 
         QUARTER(currentdate), 
         WEEKOFYEAR(currentdate), 
         DATE_FORMAT(currentdate,'%W'), 
         DATE_FORMAT(currentdate,'%M'), 
         'f', 
         CASE DAYOFWEEK(currentdate) WHEN 1 THEN 't' WHEN 7 then 't' ELSE 'f' END, 
         NULL); 
     SET currentdate = ADDDATE(currentdate,INTERVAL 1 DAY); 
    END WHILE; 
END 
// 
DELIMITER ; 

TRUNCATE TABLE time_dimension; 

CALL fill_date_dimension('1-01-01','2015-01-01'); 
OPTIMIZE TABLE time_dimension; 
+0

美麗!解決了我的問題,否則我將不得不花費2-3天的時間在拼寫所有日期。 – yardy 2011-05-01 03:41:22