Reputation: 322
Currently I'm using the below code:
SELECT DATE_SUB(example, INTERVAL 1 DAY) ,
FORMAT_DATE("%A", DATE_SUB(example, INTERVAL 1 DAY))
FROM UNNEST(GENERATE_DATE_ARRAY('2013-01-1', '2030-04-01', INTERVAL 3 MONTH)) AS example
The output which I'm getting is:
2012-12-31 Monday
2013-03-31 Sunday
2013-06-30 Sunday
2013-09-30 Monday
2013-12-31 Tuesday
2014-03-31 Monday
2014-06-30 Monday
2014-09-30 Tuesday
The expected output is:
2012-12-31 Monday
2013-03-29 Friday
2013-06-28 Friday
2013-09-30 Monday
2013-12-31 Tuesday
2014-03-31 Monday
2014-06-30 Monday
2014-09-30 Tuesday
I'm trying to extract the last working day for each quarter(3 months of timegap). But i couldn't exclude saturdays and sundays.
It would be great if someone help me to sort out this issue.
Upvotes: 0
Views: 709
Reputation: 15057
You also can calculate the diffenece to the last workday with ELT().
This function returns the difference, in days, to the last workday
ELT(dayofweek(example), '2','3','1','1','1','1','1')
Sample for MariaDB
SELECT
example as org
, example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY AS LAST_WORKDAY
, DATE_FORMAT(example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY,'%W') AS WEEKDAY
FROM (
SELECT date('2013-01-01') + interval seq MONTH as example from seq_0_to_4) as d;
Sample for MySQL
SELECT
example as org
, example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY AS LAST_WORKDAY
, DATE_FORMAT(example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY,'%W') AS WEEKDAY
FROM UNNEST(GENERATE_DATE_ARRAY('2013-01-1', '2030-04-01', INTERVAL 3 MONTH)) AS example;
Result
MariaDB [bernd]> SELECT
-> example as org
-> , example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY AS LAST_WORKDAY
-> , DATE_FORMAT(example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY,'%W') AS WEEKDAY
-> FROM (
-> SELECT date('2013-01-01') + interval seq MONTH as example from seq_0_to_4) as d ;
+------------+--------------+----------+
| org | LAST_WORKDAY | WEEKDAY |
+------------+--------------+----------+
| 2013-01-01 | 2012-12-31 | Monday |
| 2013-02-01 | 2013-01-31 | Thursday |
| 2013-03-01 | 2013-02-28 | Thursday |
| 2013-04-01 | 2013-03-29 | Friday |
| 2013-05-01 | 2013-04-30 | Tuesday |
+------------+--------------+----------+
5 rows in set (0.001 sec)
MariaDB [bernd]>
Upvotes: 0
Reputation: 173046
Consider below approach
create temp function getLastBusinessDayOfMonth(next_month_first_day date) as ((
select as struct month_last_business_day,
format_date("%A", month_last_business_day) day_of_week
from unnest([struct(next_month_first_day - 1 as month_last_day, extract(dayofweek from next_month_first_day) as adjust)]),
unnest([struct(month_last_day - if(adjust > 2, 0, adjust) as month_last_business_day)])
));
select getLastBusinessDayOfMonth(sample).*
from unnest(generate_date_array('2013-01-1', '2014-11-01', interval 3 month)) as sample
with output
Upvotes: 0
Reputation: 678
try this.
SELECT case when FORMAT_DATE("%A", DATE_SUB(example, INTERVAL 1 DAY)) = 'Sunday'
then date_sub(DATE_SUB(example, INTERVAL 1 DAY), interval 2 day)
when FORMAT_DATE("%A", DATE_SUB(example, INTERVAL 1 DAY)) = 'Saturday'
then date_sub(DATE_SUB(example, INTERVAL 1 DAY), interval 1 day)
else DATE_SUB(example, INTERVAL 1 DAY) end as d1,
case when FORMAT_DATE("%A", DATE_SUB(example, INTERVAL 1 DAY)) in ('Saturday','Sunday')
then 'Friday'
else FORMAT_DATE("%A", DATE_SUB(example, INTERVAL 1 DAY)) end
FROM UNNEST(GENERATE_DATE_ARRAY('2013-01-1', '2030-04-01', INTERVAL 3 MONTH)) AS example
order by d1
Upvotes: 1