Reputation: 656
I'm looking to do two things - I'm trying to a.) only extract business days within a month and b.) what business day it is of the month its in.
So I know the business day portion can be done by using the DAYOFWEEK function and getting rid of all days that equal 1 or 7, but I'm a bit stumped on how to solve the business day of month portion. For example, today would be the 21st business day of this month, but the 21st business day of another month might not be the 29th, so it wouldn't make sense to compare that sort of way. It could be a weekend. For the purposes of making this simple, we don't need to worry about holidays that fall on a typical business day (i.e Memorial Day).
So my goal is basically to have an output that gives you -
Column 1: ID (lets just say this is some three character randomly generated alphanumeric ID)
Column 2: start_date
Column 3: Day of week
Column 4: business day within start_date month
Anyone have any advice?
Upvotes: 0
Views: 3453
Reputation: 173046
Try below
SELECT
start_date,
business_day,
DAYOFWEEK(business_day) AS day_of_week,
ROW_NUMBER() OVER(PARTITION BY start_date ORDER BY business_day) AS business_day_number
FROM (
SELECT
start_date, DATE(DATE_ADD(TIMESTAMP(start_date), pos - 1, "DAY")) AS business_day
FROM (
SELECT start_date, ROW_NUMBER() OVER() AS pos
FROM (FLATTEN((
SELECT start_date, SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP(end_date), TIMESTAMP(start_date)), '.'),'') AS h
FROM
(SELECT '2016-01-01' AS start_date, '2016-01-31' AS end_date),
(SELECT '2016-03-01' AS start_date, '2016-03-31' AS end_date),
(SELECT '2016-06-01' AS start_date, '2016-06-30' AS end_date)
), h
)))
HAVING DAYOFWEEK(business_day) NOT IN (1,7)
)
in my mind - you changed original question - so I felt it is appropriate to provide separate answer instead of adding to my original one
where would the table name go?
assuming YourTable looks like below:
start_date end_date
2016-01-01 2016-01-31
2016-03-01 2016-03-31
2016-06-01 2016-06-30
the query will look like
SELECT
start_date,
business_day,
DAYOFWEEK(business_day) AS day_of_week,
ROW_NUMBER() OVER(PARTITION BY start_date ORDER BY business_day) AS business_day_number
FROM (
SELECT
start_date, DATE(DATE_ADD(TIMESTAMP(start_date), pos - 1, "DAY")) AS business_day
FROM (
SELECT start_date, ROW_NUMBER() OVER() AS pos
FROM (FLATTEN((
SELECT start_date, SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP(end_date), TIMESTAMP(start_date)), '.'),'') AS h
FROM YourTable), h
)))
HAVING DAYOFWEEK(business_day) NOT IN (1,7)
)
Upvotes: 1
Reputation: 173046
Extracting Business Days between Start and End Date
In below example Start Date is '2016-06-01' and End Date is '2016-06-30'
SELECT
DATE(DATE_ADD(TIMESTAMP('2016-06-01'), pos - 1, "DAY")) AS business_day
FROM (
SELECT ROW_NUMBER() OVER() AS pos, *
FROM (FLATTEN((
SELECT SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP('2016-06-30'), TIMESTAMP('2016-06-01')), '.'),'') AS h
FROM (SELECT NULL)),h
)))
HAVING DAYOFWEEK(business_day) NOT IN (1,7)
Finding Nth Business Day between Start and End Date
In below example Start Date is '2016-06-01' and End Date is '2016-06-30' and N = 21
SELECT
business_day
FROM (
SELECT
business_day,
ROW_NUMBER() OVER(ORDER BY business_day) AS number
FROM (
SELECT
DATE(DATE_ADD(TIMESTAMP('2016-06-01'), pos - 1, "DAY")) AS business_day
FROM (
SELECT ROW_NUMBER() OVER() AS pos, *
FROM (FLATTEN((
SELECT SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP('2016-06-30'), TIMESTAMP('2016-06-01')), '.'),'') AS h
FROM (SELECT NULL)),h
)))
HAVING DAYOFWEEK(business_day) NOT IN (1,7)
)
)
WHERE number = 21
Upvotes: 1