Can I calculate there's how many weekend days between two dates in SQL Server? - sql

I'm calculating income of hiring equipments for a report. In that, hiring cost in weekend days will be plus 10% more if compare with normal days. So how can I calculate there's how many weekend days between two dates. And in report query, I can't use DECLARE also. Can someone help me to do this. Thank you so much

This should work:
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #StartDate = '2012/11/01'
SET #EndDate = '2012/11/05'
SELECT
(DATEDIFF(wk, #StartDate, #EndDate) * 2)
+(CASE WHEN DATENAME(dw, #StartDate) = 'Sunday' THEN 1 ELSE 0 END)
+(CASE WHEN DATENAME(dw, #EndDate) = 'Saturday' THEN 1 ELSE 0 END)
http://sqlfiddle.com/#!3/d41d8/5707/0

Related

Adding count of Holiday days to dates between

DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #StartDate = '2012/11/01'
SET #EndDate = '2012/11/05'
SELECT
(DATEDIFF(wk, #StartDate, #EndDate) * 2)
+(CASE WHEN DATENAME(dw, #StartDate) = 'Sunday' THEN 1 ELSE 0 END)
+(CASE WHEN DATENAME(dw, #EndDate) = 'Saturday' THEN 1 ELSE 0 END)
Help to add # of holiday days to this solution? If there are any Holiday days between your start and end dates. Assuming I do have a table called BICalendar with a column isHoliday and value = 1 if that date is a holiday.
To directly answer the question:
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #StartDate = '2012/11/01'
SET #EndDate = '2012/11/05'
SELECT (DATEDIFF(wk, #StartDate, #EndDate) * 2) -- To calculate the number of weekend dates between the two input dates
+ (CASE WHEN DATENAME(dw, #StartDate) = 'Sunday' THEN 1 ELSE 0 END) --If the Start date is Sunday, then add one to adjust for non-working days
+ (CASE WHEN DATENAME(dw, #EndDate) = 'Saturday' THEN 1 ELSE 0 END) --If the End date is Saturday, then add one to adjust for non-working days
- (SELECT COUNT(*) --Minus the number of holiday dates between the two dates
FROM BICalendar
WHERE [Date] BETWEEN #STartDate AND #EndDate
AND isHoliday = 1);
I suspect what you're trying to do is calculate the number of working days between the two dates? If so, the below solution should also work:
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #StartDate = '2021-05-01'
SET #EndDate = '2021-05-15'
SELECT DATEDIFF(dd, #StartDate, #EndDate) --To calculate the number of days between the two dates
- (DATEDIFF(wk, #StartDate, #EndDate) * 2) -- To remove the weekends between the two dates
+ (CASE WHEN DATENAME(dw, #StartDate) = 'Sunday' THEN 1 ELSE 0 END) --If the Start date is Sunday, then add one to adjust for non-working days
+ (CASE WHEN DATENAME(dw, #EndDate) = 'Saturday' THEN 1 ELSE 0 END) --If the End date is Saturday, then add one to adjust for non-working days
- (SELECT COUNT(*) --Minus the number of holiday dates between the two dates
FROM BICalendar
WHERE [Date] BETWEEN #STartDate AND #EndDate
AND isHoliday = 1);

SQL Query to find out the non weekends (Monday-Friday) dates of a week from a variable date

I am writing a SQL Query to find out the non weekends dates (i.e. Monday-Friday) of a week from a variable date.
Basically, it should show the dates which are not coming in weekends (Saturday & Sunday) of the week of a given date.
E.g. If the given date is 6th January, 2021. Then the output date should be between 4th-8th January, 2021.
i.e the Week_Start_Date should be 2021-01-04 and Week_End_Date should be 2021-01-08.
I am writing below codes to find out the count of non-weekend days by referring a date and also writing a query to find out the Week_Start_Date & Week_End_Date using the referring date, but unable to combine both of these.
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #StartDate = '2021/01/04'
SET #EndDate = '2021/01/08'
SELECT
(DATEDIFF(dd, #StartDate, #EndDate) + 1)
-(DATEDIFF(wk, #StartDate, #EndDate) * 2)
-(CASE WHEN DATENAME(dw, #StartDate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, #EndDate) = 'Saturday' THEN 1 ELSE 0 END)
SELECT DATEADD(DAY, 2 - DATEPART(WEEKDAY, GETDATE()), CAST(GETDATE() AS DATE)) [Week_Start_Date],
DATEADD(DAY, 8 - DATEPART(WEEKDAY, GETDATE()), CAST(GETDATE() AS DATE)) [Week_End_Date] ;
EDIT:
I am getting the required output using below SQL query :-
SELECT DATEADD(wk,DATEDIFF(wk,0,GETDATE()),0)
SELECT DATEADD(wk,DATEDIFF(wk,0,GETDATE()),4)
I am getting the required output using below SQL query :-
SELECT DATEADD(week,DATEDIFF(week,0,GETDATE()),0)
SELECT DATEADD(week,DATEDIFF(week,0,GETDATE()),4)

count week days in sql by datediff [duplicate]

This question already has answers here:
Count work days between two dates
(24 answers)
Calculating days to excluding weekends (Monday to Friday) in SQL Server
(6 answers)
Closed 7 years ago.
I'm looking for a way to calculate the days between two dates, but on weekdays. Here is the formula, but it counts weekend days.
DATEDIFF(DAY,STARTDATE,ENDDATE)
SELECT DATEDIFF(DAY,'2015/06/01' , '2015/06/30')
Result of above query of datediff is 29 days which are weekend days. but i need week days that should be 21 by removing Saturday and Sunday(8 days).
Any suggestions?
Put it in the WHERE clause
SELECT DATEDIFF(DAY,'2015/06/01' , '2015/06/30')
FROM yourtable
WHERE DATENAME(dw, StartDate) != 'Saturday'
AND DATENAME(dw, StartDate) != 'Sunday'
Or all in a SELECT statement
SELECT (DATEDIFF(dd, StartDate, EndDate) + 1)-(DATEDIFF(wk, StartDate, EndDate) * 2)-(CASE WHEN DATENAME(dw, StartDate) = 'Sunday' THEN 1 ELSE 0 END)-(CASE WHEN DATENAME(dw, EndDate) = 'Saturday' THEN 1 ELSE 0 END)
This returns 22:
DECLARE #StartDate AS DATE = '20150601'
DECLARE #EndDate AS DATE = '20150630'
SELECT
(DATEDIFF(DAY, #StartDate, #EndDate))
-(DATEDIFF(WEEK, #StartDate, #EndDate) * 2)
-(CASE WHEN DATENAME(dw, #StartDate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, #EndDate) = 'Saturday' THEN 1 ELSE 0 END)
Read this article by Jeff Moden for more information.
Explanation:
First, (DATEDIFF(DAY, #StartDate, #EndDate)) will return the difference in number of days. In this case, it'll be 29. Now, depending on your interpretation of whole days, you may want to add 1 day to its result.
Next,(DATEDIFF(WEEK, #StartDate, #EndDate) * 2):
To quote the article:
DATEDIFF for the WEEK datepart doesn't actually calculate weeks, it
calculates the number of times a date range contains dates that
represent pairs of Saturdays and Sundays. To think of it in more
simple terms, it only counts WHOLE WEEKENDS!
So, to exclude the weekends, you must subtract twice the result of this from the first DATEDIFF. Which now will be: 29 - (2 *4) = 21.
Finally, this:
-(CASE WHEN DATENAME(dw, #StartDate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, #EndDate) = 'Saturday' THEN 1 ELSE 0 END)
removes the partial weeks, which only happens when then #StartDate occurs on a Sunday and the #EndDate occurs on a Saturday.
You can try recursive cte:
WITH cte
AS ( SELECT CAST('2015/06/01' AS DATE) AS dt ,
DATEPART(WEEKDAY, '2015/06/01') AS wd
UNION ALL
SELECT DATEADD(d, 1, dt) AS dt ,
DATEPART(WEEKDAY, DATEADD(d, 1, dt))
FROM cte
WHERE dt < '2015/06/30'
)
SELECT COUNT(*)
FROM cte
WHERE wd NOT IN ( 7, 1 )
Result is 22.
You better add some useful calendar table that every database should have. Fill it with some big range and then use it to calculate business days.
I wrote a simple stored procedure - don't know if a SP is what you need but i think you can easily convert it to a function , TVF, whatever:
CREATE PROCEDURE [dbo].[BusinessdaysBetween](#DateFrom DATE, #DateTo DATE, #days INT OUTPUT)
AS
BEGIN
DECLARE #datefirst INT = ##DATEFIRST
SET DATEFIRST 1 --so week starts on monday
SET #days = 0
IF #DateFrom > #DateTo
RETURN NULL
IF #DateFrom = #DateTo
RETURN #days
WHILE #DateFrom <= #DateTo
BEGIN
IF DATEPART(WEEKDAY,#DateFrom) NOT IN (6,7) --Saturday or Sunday
BEGIN
SET #days = #days + 1
END
SET #DateFrom = DATEADD(DAY,1,#DateFrom)
END
SET DATEFIRST #datefirst --restore original setup
END
GO
in my example i call i it like this:
DECLARE #days INT = 0
DECLARE #datefrom DATETIME = GETDATE()
DECLARE #dateto DATETIME = DATEADD(DAY,25,GETDATE())
EXEC dbo.BusinessdaysBetween #datefrom, #dateto, #days OUTPUT
SELECT #days

Calculations excluding weekends

I am trying to make a holiday booking application and it runs of a JQuery UI calendar. the star and end date they select are passed to SQL where it puts the holiday into the requested table. the only problem is if i put a start and an end date in, it doesn't take into account the weekends. each user of the system has 21 days allowance off per calendar year and it deducts the weekends of this also. here is the current code.
SET #DateDiff = (DATEDIFF(Day,#StartDate,#EndDate) +1)
Above is the date-diff statement and below is the insertion code
BEGIN
INSERT INTO Holidays(EmployeeID, StartDate, EndDate, Duration,Status)
VALUES(#EmployeeID, #StartDate, #EndDate, #DateDiff,'PE')
UPDATE Employees
SET AnnualDaysHolidayAllowance = AnnualDaysHolidayAllowance - #DateDiff
WHERE ID = #EmployeeID
SELECT 'successful' AS result
END
There is more code for the business checks and rules but this is the only part i need to try and fix. i am relatively new to coding so if possible please leave an explanation to help me understand the fix, thanks.
Found the solution it was on the link posted.
source: Count work days between two dates
The answer (not my own work)
SET #DateDiff = (SELECT
(DATEDIFF(dd, #StartDate, #EndDate) + 1)
-(DATEDIFF(wk, #StartDate, #EndDate) * 2)
-(CASE WHEN DATENAME(dw, #StartDate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, #EndDate) = 'Saturday' THEN 1 ELSE 0 END))

Number of working days between two dates

I want number of working days in between to dates. For example if we have 01-01-2012 and 20-01-2012, i want to get the number of working days in between that two dates using T-SQL.
Since SQL Server has no idea what your company considers working days, the best answer to this problem is likely going to be to use a calendar table. Once you have a table with past and future dates, with a column like IsWorkDay correctly updated, the query is simple:
SELECT [Date] FROM dbo.Calendar
WHERE [Date] >= #start
AND [Date] <= #end
AND IsWorkDay = 1;
DECLARE #fromDate datetime, #toDate datetime
SELECT #fromDate = ' 01-01-2012', #toDate = '20-01-2012'
SELECT (DATEDIFF(day, #fromDate, #toDate) + 1)
- (DATEDIFF(week, #fromDate, #toDate) * 2)
- (CASE WHEN DATENAME(weekday, #fromDate) = 'Sunday' THEN 1 ELSE 0 END)
- (CASE WHEN DATENAME(weekday, #toDate) = 'Saturday' THEN 1 ELSE 0 END)
I liked Aaron Bertrand's suggestion so I wrote this code that can be added to your queries. It creates a table variable between 2 dates that you can then use in your query by joining on the CalendarDate column (just remember to strip out any time information before joining). This is based on the typical American work week of Monday through Friday.
DECLARE #StartDate DATE
DECLARE #EndDate DATE
SET #StartDate = '2013-08-19'
SET #EndDate = '2013-08-26'
DECLARE #BusinessDay TABLE
(
CalendarDate DATETIME,
IsBusinessDay INT
)
DECLARE #Counter DATETIME = #StartDate
WHILE(#Counter <= #EndDate)
BEGIN
INSERT INTO #WorkDays
SELECT #Counter, CASE WHEN DATENAME(WEEKDAY, #Counter) NOT IN ('Saturday', 'Sunday') THEN 1 ELSE 0 END
SET #Counter = DATEADD(DAY, 1, #Counter)
END
SELECT * FROM #BusinessDay
The downside is this has to be recreated for each query that needs it, so if you're doing this often, a fixed table might be a better way to go.
It can be used like this....
SELECT
BusinessDays = SUM(IsBusinessDay)
FROM
#BusinessDay
WHERE
CalendarDate BETWEEN #StartDate AND #EndDate
That will give you the count of business days between the two dates. Like many others have said, this obviously does not take into account any holidays or my birthday.
Based on previous code, I adapted it to exclude the last day (not asked but I needed it).
select (DATEDIFF(dd,#fromDate, #toDate))
- (DATEDIFF(ww,#fromDate, DATEADD(dd,-1,#toDate)) * 2)
- (CASE WHEN DATENAME(dw, #fromDate) = 'Sunday' THEN 1 else 0 end)
- (CASE WHEN DATENAME(dw, #toDate) = 'Sunday' THEN 1 else 0 end)
I removed the holydays by using a table containing those dates
- ( select count(distinct dcsdte)
from calendar_table
where dcsdte between #fromDate
and #toDate )