Last active
March 26, 2023 22:38
-
-
Save negri/c841b909baaa2701c50c391c7195ab03 to your computer and use it in GitHub Desktop.
Return the first and last work day of each month, on Sql Server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Returns information about the first and last work day of every month | |
-- Assumes that no one messed with the `SET DATEFIRST` option and Sunday is 1 and Saturday is 7 | |
-- Requires a table, `Market.Holiday`, containing the columns `BusinessCenterCode` and `Date`, containing the place and every holiday on that place. | |
-- Be carefull with the first month and last one: will only be correct if you put holidays "guards" on the `Holiday` table. | |
select DATEPART(year, [Date]) as [Year], DATEPART(month, [Date]) as [Month], min([Date]) as FirstWorkDay, max([Date]) as LastWorkDay, count(1) as NumWorkDays | |
from | |
( | |
SELECT | |
DATEADD(day, Unity+Tens+Hundreds+Thousands+TensOfThousands, (SELECT MIN(Date) FROM Market.Holiday WHERE BusinessCenterCode = 'br-BC')) as [Date] | |
FROM ( | |
SELECT 0 AS Unity UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 | |
) u1 | |
CROSS JOIN ( | |
SELECT 0 AS Tens UNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30 UNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60 UNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90 | |
) u2 | |
CROSS JOIN ( | |
SELECT 0 AS Hundreds UNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300 UNION ALL SELECT 400 UNION ALL SELECT 500 UNION ALL SELECT 600 UNION ALL SELECT 700 UNION ALL SELECT 800 UNION ALL SELECT 900 | |
) u3 | |
CROSS JOIN ( | |
SELECT 0 AS Thousands UNION ALL SELECT 1000 UNION ALL SELECT 2000 UNION ALL SELECT 3000 UNION ALL SELECT 4000 UNION ALL SELECT 5000 UNION ALL SELECT 6000 UNION ALL SELECT 7000 UNION ALL SELECT 8000 UNION ALL SELECT 9000 | |
) u4 | |
CROSS JOIN ( | |
SELECT 0 AS TensOfThousands UNION ALL SELECT 10000 UNION ALL SELECT 20000 UNION ALL SELECT 30000 UNION ALL SELECT 40000 UNION ALL SELECT 50000 UNION ALL SELECT 60000 UNION ALL SELECT 70000 UNION ALL SELECT 80000 UNION ALL SELECT 90000 | |
) u5 | |
) AllDates | |
where | |
[Date] >= (select min([Date]) from Market.Holiday where BusinessCenterCode = 'br-BC') | |
and [Date] <= (select max([Date]) from Market.Holiday where BusinessCenterCode = 'br-BC') | |
and DATEPART(weekday, [Date]) not in (1, 7) | |
and [Date] not in (select [Date] from Market.Holiday where BusinessCenterCode = 'br-BC') | |
group by DATEPART(year, [Date]), DATEPART(month, [Date]) | |
order by min([Date]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Better performance, without the row_number function.