Created
January 31, 2025 21:37
-
-
Save justincjahn/b9e43cb6cd54fad13f01ca1314bc0ede to your computer and use it in GitHub Desktop.
Dynamically generated date table in DB2
This file contains 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
WITH DATES AS ( | |
-- Dynamically generated date table spanning 999 days in the past and future. | |
SELECT | |
n AS THE_OFFSET_FROM_TODAY | |
, THE_DATE | |
, THE_DAY | |
, CASE | |
WHEN THE_DAY / 10 = 1 THEN 'th' | |
ELSE CASE RIGHT(THE_DAY, 1) | |
WHEN '1' THEN 'st' | |
WHEN '2' THEN 'nd' | |
WHEN '3' THEN 'rd' | |
ELSE 'th' | |
END | |
END AS THE_DAY_SUFFIX | |
, THE_DAY_NAME | |
, THE_DAY_OF_WEEK | |
, ROW_NUMBER() OVER (PARTITION BY THE_FIRST_OF_MONTH, THE_DAY_OF_WEEK) AS THE_DAY_OF_WEEK_IN_MONTH | |
, THE_DAY_OF_YEAR | |
, CASE | |
WHEN THE_DAY_OF_WEEK IN (1, 7) THEN TRUE | |
ELSE FALSE | |
END AS IS_WEEKEND | |
, THE_WEEK | |
, THE_WEEK_ISO | |
, THE_DATE - (THE_DAY_OF_WEEK - 1) DAYS AS THE_FIRST_OF_WEEK | |
, (THE_DATE - (THE_DAY_OF_WEEK - 1) DAYS) + 6 DAYS AS THE_LAST_OF_WEEK | |
, DENSE_RANK() OVER (PARTITION BY THE_YEAR, THE_MONTH ORDER BY THE_WEEK) AS THE_WEEK_OF_MONTH | |
, THE_MONTH | |
, THE_MONTH_NAME | |
, THE_FIRST_OF_MONTH | |
, THE_LAST_OF_MONTH | |
, THE_FIRST_OF_MONTH + 1 DAY AS THE_FIRST_OF_NEXT_MONTH | |
, LAST_DAY(THE_FIRST_OF_MONTH + 1 DAY) AS THE_LAST_OF_NEXT_MONTH | |
, THE_QUARTER | |
, MIN(THE_DATE) OVER (PARTITION BY THE_YEAR, THE_QUARTER) AS THE_FIRST_OF_QUARTER | |
, MAX(THE_DATE) OVER (PARTITION BY THE_YEAR, THE_QUARTER) AS THE_LAST_OF_QUARTER | |
, THE_YEAR | |
, THE_YEAR - CASE | |
WHEN THE_MONTH = 1 AND THE_WEEK_ISO > 51 THEN 1 | |
WHEN THE_MONTH = 12 AND THE_WEEK_ISO = 1 THEN -1 | |
ELSE 0 | |
END AS THE_ISO_YEAR | |
, DATE(THE_YEAR || '-01-01') AS THE_FIRST_OF_YEAR | |
, THE_LAST_OF_YEAR | |
, CASE | |
WHEN (THE_YEAR % 400 = 0) OR (THE_YEAR % 4 = 0 AND THE_YEAR % 100 <> 0) THEN TRUE | |
ELSE FALSE | |
END AS IS_LEAP_YEAR | |
, WEEK(THE_LAST_OF_YEAR) = 53 AS HAS_53_WEEKS | |
, WEEK_ISO(THE_LAST_OF_YEAR) = 53 AS HAS_53_ISO_WEEKS | |
, YEAR(THE_DATE) || '-' || RIGHT('0' || MONTH(THE_DATE), 2) AS YYYYMM | |
FROM ( | |
SELECT | |
n | |
, CAST(d as DATE) as THE_DATE | |
, DAY(d) as THE_DAY | |
, DAYNAME(d) as THE_DAY_NAME | |
, WEEK(d) as THE_WEEK | |
, WEEK_ISO(d) as THE_WEEK_ISO | |
, DAYOFWEEK(d) as THE_DAY_OF_WEEK | |
, MONTH(d) as THE_MONTH | |
, MONTHNAME(d) as THE_MONTH_NAME | |
, QUARTER(d) as THE_QUARTER | |
, YEAR(d) as THE_YEAR | |
, (d - (DAY(d) - 1) DAYS) as THE_FIRST_OF_MONTH | |
, LAST_DAY(d) AS THE_LAST_OF_MONTH | |
, LAST_DAY(YEAR(d) || '-12-01') AS THE_LAST_OF_YEAR | |
, DAYOFYEAR(d) AS THE_DAY_OF_YEAR | |
FROM ( | |
SELECT | |
n, | |
CURRENT_DATE + n DAYS as d | |
FROM ( | |
SELECT | |
(n1.n + n10.n + n100.n + n1000.n) * -1 AS n | |
FROM | |
(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS n1(n) | |
CROSS JOIN | |
(VALUES(0),(10),(20),(30),(40),(50),(60),(70),(80),(90)) AS n10(n) | |
CROSS JOIN | |
(VALUES(0),(100),(200),(300),(400),(500),(600),(700),(800),(900)) AS n100(n) | |
CROSS JOIN | |
(VALUES(0),(1000),(2000),(3000),(4000),(5000),(6000),(7000),(8000),(9000)) AS n1000(n) | |
WHERE | |
n1.n + n10.n + n100.n + n1000.n > 0 | |
UNION | |
SELECT | |
n1.n + n10.n + n100.n + n1000.n AS n | |
FROM | |
(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS n1(n) | |
CROSS JOIN | |
(VALUES(0),(10),(20),(30),(40),(50),(60),(70),(80),(90)) AS n10(n) | |
CROSS JOIN | |
(VALUES(0),(100),(200),(300),(400),(500),(600),(700),(800),(900)) AS n100(n) | |
CROSS JOIN | |
(VALUES(0),(1000),(2000),(3000),(4000),(5000),(6000),(7000),(8000),(9000)) AS n1000(n) | |
) t1 | |
) t2 | |
) t3 | |
) | |
SELECT | |
* | |
FROM DATES | |
ORDER BY THE_OFFSET_FROM_TODAY |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment