I have created the following calendar table:
WITH dates AS (
SELECT EXPLODE(SEQUENCE(TO_DATE('1970-01-01'), TO_DATE('2100-12-31'), INTERVAL 1 DAY)) AS calendar_date
),
calendar_table AS (
SELECT
YEAR(calendar_date) * 10000 + MONTH(calendar_date) * 100 + DAY(calendar_date) AS date_integer,
calendar_date,
YEAR(calendar_date) AS year_of_date,
QUARTER(calendar_date) AS quarter_of_year,
MONTH(calendar_date) AS month_of_year,
DAY(calendar_date) AS day_of_month,
WEEKDAY(calendar_date) + 1 AS day_of_week_start_monday,
DAYOFWEEK(calendar_date) AS day_of_week_start_sunday,
CASE
WHEN DAY(calendar_date) >= 1 AND DAY(calendar_date) <= 7 THEN 1
WHEN DAY(calendar_date) >= 8 AND DAY(calendar_date) <= 14 THEN 2
WHEN DAY(calendar_date) >= 15 AND DAY(calendar_date) <= 21 THEN 3
WHEN DAY(calendar_date) >= 22 AND DAY(calendar_date) <= 28 THEN 4
ELSE 5
END AS day_of_week_ordinal,
CASE
WHEN WEEKDAY(calendar_date) < 5 THEN TRUE
ELSE FALSE
END AS is_week_day,
CASE
WHEN WEEKDAY(calendar_date) > 4 THEN TRUE
ELSE FALSE
END AS is_weekend,
CASE
WHEN calendar_date = DATE_TRUNC('month', calendar_date)::DATE THEN TRUE
ELSE FALSE
END AS is_first_day_of_month,
CASE
WHEN calendar_date = LAST_DAY(calendar_date) THEN TRUE
ELSE FALSE
END AS is_last_day_of_month,
DAYOFYEAR(calendar_date) AS day_of_year,
WEEKOFYEAR(calendar_date) AS iso_week_of_year,
EXTRACT(YEAROFWEEK FROM calendar_date) AS iso_year_of_date,
FROM
dates
)
I am missing a custom calendar column that would abide by the following rule:
- From the second Sunday (inclusive) in December of each year, the column should contain a concatenation of 'X' and the year number of the following year.
Example:
calendar_date | custom_column |
---|---|
2022-12-10 | X2022 |
2022-12-11 | X2023 |
2022-12-12 | X2023 |
... | ... |
2023-12-09 | X2023 |
2023-12-10 | X2024 |
2023-12-11 | X2024 |
So far, I've been able to identify the second Sunday of December in each year by combining the logic behind the columns month_of_year
, day_of_week_ordinal
and day_of_week_start_monday
in my calendar table, but I fail to grasp any implementation (I'm sure I'm missing something simple here).
I can calculate a flag for the second Sunday in December of each year by utilising the following logic:
CASE
WHEN
month_of_year = 12
AND day_of_week_ordinal = 2
AND day_of_week_start_monday = 7 THEN TRUE
ELSE FALSE
END AS second_sunday_in_month
But I fail to see how I can get transfer this logic to what I want as the end result.
Edit: I have added a PostgreSQL fiddle as an interactive example.