Home > Enterprise >  Get days of the week from a date range in Postgres
Get days of the week from a date range in Postgres

Time:06-02

So I have the following table :

id     end_date      name      number_of_days    start_date
1   "2022-01-01"    holiday1        1            "2022-01-01"
2   "2022-03-20"    holiday2        1            "2022-03-20"
3   "2022-04-09"    holiday3        1            "2022-04-09"
4   "2022-05-01"    holiday4        1            "2022-05-01"
5   "2022-05-04"    holiday5        3            "2022-05-02"
6   "2022-07-12"    holiday6        9            "2022-07-20"

I want to check if a week falls in a holiday range.

So far I can select the holidays that overlap with my choosen week( week_start_date, week_end_date) , but i cant get the exact days in which the overlap happens.

this is the query i'm using, i want to add a mechanism to detect the DAYS OF THE WEEK IN WHICH THE OVERLAP HAPPENS

SELECT * FROM holidays
where daterange(CAST(start_date AS date), CAST(end_date as date), '[]') && daterange('2022-07-18', '2022-07-26','[]')

THE CURRENT QUERY RETURNS THE OVERLLAPPING HOLIDA, (id = 6), however i'm trying to get the exact DAYS OF THE WEEK in which the overlap happens ( in this case, it should be monday,tuesday , wednesday)

CodePudding user response:

You can use the * operator with tsranges, generate a series of dates with the lower and upper dates and finally with to_char print the days of the week, e.g.

SELECT 
  id, name, start_date, end_date, array_agg(dow) AS days
FROM (
  SELECT *,  
    trim(
      to_char(
        generate_series(lower(overlap), upper(overlap),'1 day'),
      'Day')) AS dow
  FROM holidays
  CROSS JOIN LATERAL (SELECT tsrange(start_date,end_date) * 
                             tsrange('2022-07-18', '2022-07-26')) t (overlap)
  WHERE tsrange(start_date,end_date) && tsrange('2022-07-18', '2022-07-26')) j
GROUP BY id,name,start_date,end_date,number_of_days;

 id |   name   | start_date |  end_date  |            days            
---- ---------- ------------ ------------ ----------------------------
  6 | holiday6 | 2022-07-12 | 2022-07-20 | {Monday,Tuesday,Wednesday}
(1 row)

Demo: db<>fiddle

  • Related