-
-
Save foshdafosh/9a5242f3df0e01d4ad782bf1379eefc2 to your computer and use it in GitHub Desktop.
MySQL Date Dimension Build Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Adapted from Tom Cunningham's 'Data Warehousing with MySql' (www.meansandends.com/mysql-data-warehouse) */ | |
###### small-numbers table | |
DROP TABLE IF EXISTS dim_numbers_small; | |
CREATE TABLE dim_numbers_small (number INT); | |
INSERT INTO dim_numbers_small VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); | |
###### main numbers table | |
DROP TABLE IF EXISTS dim_numbers; | |
CREATE TABLE dim_numbers (number BIGINT); | |
INSERT INTO dim_numbers | |
SELECT thousands.number * 1000 + hundreds.number * 100 + tens.number * 10 + ones.number | |
FROM dim_numbers_small thousands, dim_numbers_small hundreds, dim_numbers_small tens, dim_numbers_small ones | |
LIMIT 1000000; | |
###### time table | |
DROP TABLE IF EXISTS dim_times; | |
CREATE TABLE dim_times ( | |
time_id BIGINT PRIMARY KEY, | |
time TIME, | |
hour_12 INT, | |
hour_12_period CHAR(2), | |
hour INT, | |
minute INT, | |
core_hour INT, | |
standard_day INT | |
); | |
###### populate it with minutes | |
INSERT INTO dim_times (time_id, time) | |
SELECT number, DATE_ADD( '1970-01-01 00:00:00', INTERVAL number MINUTE ) | |
FROM dim_numbers | |
ORDER BY number | |
LIMIT 1440; | |
UPDATE dim_times SET | |
hour_12 = time_format(time, '%h'), | |
hour_12_period = time_format(time, '%p'), | |
hour = hour(time), | |
minute = minute(time), | |
core_hour = if(hour between 9 and 16,1,0), | |
standard_day = 1 | |
; | |
###### date table | |
/* Additional fields to add later? | |
isthismonth | |
ispreviousfullmonth | |
*/ | |
DROP TABLE IF EXISTS dim_dates; | |
CREATE TABLE dim_dates ( | |
date_id BIGINT PRIMARY KEY, | |
julian_date BIGINT, | |
date DATE NOT NULL, | |
timestamp BIGINT, | |
istoday INT NOT NULL DEFAULT 0, | |
isyesterday INT NOT NULL DEFAULT 0, | |
isweekend INT NOT NULL DEFAULT 0, | |
isworkday INT NOT NULL DEFAULT 1, | |
isthisweek INT NOT NULL DEFAULT 0, | |
islastweek INT NOT NULL DEFAULT 0, | |
isbankholiday INT NOT NULL DEFAULT 0, | |
bankholidaydesc char(20), | |
weekend_text CHAR(10) NOT NULL DEFAULT "Weekday", | |
day_of_week_full CHAR(10), | |
day_of_week_short CHAR(3), | |
day_of_week INT, | |
month INT, | |
month_full CHAR(10), | |
month_short CHAR(3), | |
first_date_of_month DATE, | |
last_date_of_month DATE, | |
days_in_month INT, | |
day_of_month INT, | |
day_of_month_text CHAR(5), | |
quarter INT, | |
year INT, | |
year_month_number INT, | |
year_quarter_number INT, | |
year_week_number INT, | |
day_of_year INT, | |
week_starting_monday CHAR(2), | |
UNIQUE KEY `date` (`date`), | |
KEY `year_week` (`year`,`week_starting_monday`) | |
); | |
###### populate it with days | |
INSERT INTO dim_dates (date_id, date) | |
SELECT number, DATE_ADD( '2012-01-01', INTERVAL number DAY ) | |
FROM dim_numbers | |
WHERE DATE_ADD( '2012-01-01', INTERVAL number DAY ) BETWEEN '2012-01-01' AND '2022-01-01' | |
ORDER BY number; | |
###### fill in other rows | |
UPDATE dim_dates SET | |
timestamp = UNIX_TIMESTAMP(date), | |
julian_date = TO_DAYS(date), | |
day_of_week = IF(DATE_FORMAT( date, "%w" ) = 0,7,DATE_FORMAT( date, "%w" )), | |
day_of_week_full = DATE_FORMAT( date, "%W" ), | |
day_of_week_short = DATE_FORMAT( date, "%a" ), | |
weekend_text = IF( DATE_FORMAT( date, "%W" ) IN ('Saturday','Sunday'), 'Weekend', 'Weekday'), | |
istoday = IF( date = CURDATE(), 1, 0), | |
isyesterday = IF( date = (CURDATE()-1), 1, 0), | |
isweekend = IF( DATE_FORMAT( date, "%W" ) IN ('Saturday','Sunday'), 1, 0), | |
isworkday = IF( DATE_FORMAT( date, "%W" ) IN ('Saturday','Sunday'), 0, 1), | |
isthisweek = IF( YEARWEEK(date, 1) = YEARWEEK(CURDATE(), 1), 1, 0), | |
islastweek = IF( YEARWEEK(date, 1) = (YEARWEEK(CURDATE(), 1)-1), 1, 0), | |
month = DATE_FORMAT( date, "%m"), | |
month_full = DATE_FORMAT( date, "%M"), | |
month_short = DATE_FORMAT( date, "%b"), | |
first_date_of_month= date_add(date,interval -DAY(date)+1 DAY), | |
last_date_of_month = LAST_DAY(date), | |
days_in_month = DAY(LAST_DAY(date)), | |
quarter = QUARTER( date ), | |
year = DATE_FORMAT( date, "%Y" ), | |
year_month_number = CONCAT(DATE_FORMAT(date, "%Y"),DATE_FORMAT(date, "%m")), | |
year_quarter_number = CONCAT(DATE_FORMAT(date, "%Y"),QUARTER(date)), | |
year_week_number = CONCAT(DATE_FORMAT(date, "%Y"),DATE_FORMAT(date, "%v")), | |
day_of_month = DATE_FORMAT( date, "%d" ), | |
day_of_month_text = DATE_FORMAT( date, "%D" ), | |
day_of_year = DATE_FORMAT( date, "%j" ); | |
###### fill in other rows - second pass | |
UPDATE dim_dates SET week_starting_monday = DATE_FORMAT(date,'%v'); | |
###### ideally populate bank holidays from https://www.gov.uk/bank-holidays / https://www.gov.uk/bank-holidays/england-and-wales.ics |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment