自动填充时间维度表

时间:2012-03-06 12:18:26

标签: mysql sql database debian data-warehouse

我目前正在处理一个报告项目。在我的数据仓库中,我需要一个包含所有日期的维度表“时间”(自2011年1月1日起可能?),并且每天都会自动递增,格式为yyyy-mm-dd。 我顺便在Debian上使用MySQL。 谢谢 JT

4 个答案:

答案 0 :(得分:1)

您可以添加DATE字段并使用这样的查询 -

INSERT INTO table(date_column, column1, column2)
  VALUES(DATE(NOW()), 'value1', 'value2');

此外,您可以使用ON UPDATE CURRENT_TIMESTAMP添加TIMESTAMP列,在这种情况下,日期时间值将自动更新。

Automatic Initialization and Updating for TIMESTAMP

答案 1 :(得分:1)

See this answer

Or This one

那里有很多建议。如果您的日期范围适中,可能是一年或两年,并且假设您的报告使用存储过程来返回结果,您可以使用rownum技术动态创建临时表,并使用限制来获取所有范围内的日期。然后根据需要加入您的数据。

根据评论,第二个答案中的联盟技巧似乎没有成功,并且可以扩展到您需要的任何最大范围。虽然这很麻烦!

答案 2 :(得分:1)

article似乎涵盖了您想要的内容。另请参阅this question,了解您可能希望在表中使用的列的另一个示例。你肯定应该提前生成大量的日期,而不是每天更新表格;它节省了大量的工作和复杂性。 100年只有~36500行,这是一张小桌子。

临时表或过程代码不是数据仓库的好解决方案,因为您希望报表工具能够访问维表。如果您的RDBMS对星型模式查询进行了优化(我不知道MySQL是否存在),那么它也需要查看维度。

答案 3 :(得分:0)

以下是我用来创建和填充时间维度表的内容:

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')),
        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
            );
        SET currentdate = ADDDATE(currentdate,INTERVAL 1 DAY);
    END WHILE;
END
//
DELIMITER ;

TRUNCATE TABLE time_dimension;
CALL fill_date_dimension('1800-01-01','2050-01-01');
OPTIMIZE TABLE time_dimension;