Skip to content

Instantly share code, notes, and snippets.

@justincjahn
Created January 31, 2025 21:37
Show Gist options
  • Save justincjahn/b9e43cb6cd54fad13f01ca1314bc0ede to your computer and use it in GitHub Desktop.
Save justincjahn/b9e43cb6cd54fad13f01ca1314bc0ede to your computer and use it in GitHub Desktop.
Dynamically generated date table in DB2
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