Get number of weekends between two dates in SQL - sql-server

I need to get the number of weekends between dates in sql as a function. I have tried but stuck up somewhere in the logic.
CREATE FUNCTION fnc_NumberOfWeekEnds(#dFrom DATETIME, #dTo DATETIME)
RETURNS INT AS
BEGIN
Declare #weekends int
Set #weekends = 0
While #dFrom <= #dTo Begin
If ((datepart(dw, #dFrom) = 1))
Set #weekends = #weekends + 1
Set #dFrom = DateAdd(d, 1, #dFrom)
End
Return (#weekends)
END

I tried out this logic with several edge cases and it seems to work.
SELECT DATEDIFF(d, #dFrom, #dTo)/7+1
+ CASE WHEN DATEPART(dw,#dFrom) IN (1,7) THEN -1 ELSE 0 END
+ CASE WHEN DATEPART(dw,#dTo) IN (1,7) THEN -1 ELSE 0 END
You can change the CASE statements depending on how you want to handle cases where the start or end date is in a weekend. In my case I'm not including the weekend if the start or end date is a Saturday or Sunday.

Try replacing the if statement with this:
If ((datepart(dw, #dFrom) = 1) OR (datepart(dw, #dFrom) = 7))
You should also check the end of the week to get the result.

DECLARE #date_from DATETIME,
#date_to DATETIME
/*TEMPORARY TABLE*/
DECLARE #DATES AS TABLE (
GDate DATETIME
)
SELECT #date_from ='2019-09-10'
SELECT #date_to ='2019-10-10'
/*DATE GENERATED*/
WITH dates
AS (
SELECT #date_from AS dt
UNION ALL
SELECT DATEADD(D, 1, dt)
FROM dates
WHERE dt < #date_to
)
/*INSERTED DATES INTO TEMP TABLE */
INSERT INTO #DATES
SELECT CONVERT(DATETIME, dt) AS Gdate FROM dates
/*Get Records from temp table*/
SELECT Gdate FROM #DATES

Used below logic to calculate the no of Saturdays or Sundays between a start date and end date.
CREATE FUNCTION dbo.WEEKEND_COUNT
(
#Start_Date datetime,
#End_Date datetime
)
RETURNS int
AS
BEGIN
Declare #count int = 0;
while #Start_Date<=#End_Date
Begin
IF DatePart(WEEKDAY,#Start_Date) = 1 or DatePart(WEEKDAY,#Start_Date) = 7
SET #count=#count+1
SET #Start_Date=DateAdd(d,1,#Start_Date)
END
return #count
END
--Use below to get the count of Saturdays and Sundays
Select dbo.WEEKEND_COUNT('Your start date','your end date')

This will give you the number of sunday between two dates
SELECT DateDiff(ww, #dFrom, #dTo) as NumOfSundays

Related

find latest date between created date and updated date in sql stored procedure [duplicate]

This question already has answers here:
Selecting most recent date between two columns
(13 answers)
Closed 3 years ago.
I have two column in my table as created date and updated date.I want to find latest date from that.which ever is latest I want to considered that and filter it from input values.
My current query is :-
Select *
from Emp E
WHERE (E.USERID=#UserID) and (E.CDATE >= #FromDate AND E.CDATE <= #ToDate) order by qdate desc
You can subtract fromDate and toDate with system date to find the latest date. And by using case you can filter based on the latest date.
Like:
SELECT *
FROM Emp E
WHERE ( E.USERID = #UserID )
AND E.CDATE = CASE WHEN #fromdate - GETDATE() > #toDate - GETDATE()
THEN #fromdate
ELSE #toDate
END;
To find the latest date between two dates, you can use reference of the script below.
DECLARE #fromdate DATETIME, #toDate DATETIME, #date DATETIME
SET #fromdate = '2019-04-05'
SET #toDate = '2019-05-05'
SET #date = CASE WHEN #fromdate - GETDATE() > #toDate - GETDATE() THEN #fromdate
ELSE #toDate
END;
SELECT #date;
SELECT *
FROM Emp E
WHERE (E.USERID = #UserID)
AND 1 = CASE
WHEN E.CDATE >= E.UDATE
THEN CASE
WHEN (
E.CDATE >= #FromDate
AND E.CDATE <= #ToDate
)
THEN 1
END
WHEN E.CDATE < E.UDATE
THEN CASE
WHEN (
E.UDATE >= #FromDate
AND E.UDATE <= #ToDate
)
THEN 1
END
ELSE 0
END
assuming update date is UDATE
select *
from Emp E
where (E.USERID=#UserID)
and (SELECT MAX(V) from (values(E.CDATE), (E.UDATE)) MAX_DATE(V)) BETWEEN #FromDate AND #ToDate
declare #cdate smalldatetime,#udate smalldatetime
Select CDATE=max(CDATE ) ,UDATE =max(UDATE ) into #tbldate
from Emp
set #cdate =(select CDATE from #tbldate)
set #udate =(select udate from #tbldate)
if(#cdate>#udate)
begin
Select CDATE as Latest_Date from #tbldate
end
else
begin
Select UDATE as Latest_Date from #tbldate
end
//Run this by selecting all

How to to pass a date to a stored procedure?

I have the following SP:
IF EXISTS (SELECT * FROM [dbo].[Assignments]
WHERE ProjectId=#ProjectUID AND TaskId=#TaskUID AND ResourceId=#ResourceUID
AND (StartDate <= #DATE AND FinishDate >= #DATE)
)
BEGIN
Return 1
END
ELSE
BEGIN
Return 2
END
When I executed it with some parameters, it's returns me 2(I have taken this parameter for my date #Date = '2018-11-02') so I decided to try in select statement, and the select statement return me a line and if I put my Line with start and end date in comments, my SP works
So I know that my trouble is coming from the date
But I don't understand why
PS: I have already tried with a between but the result is the same
Compare dates using the date parts of datetime columns:
IF EXISTS (
SELECT *
FROM [dbo].[Assignments]
WHERE
ProjectId = #ProjectUID AND
TaskId = #TaskUID AND
ResourceId = #ResourceUID AND
(CONVERT(date, StartDate) <= #DATE AND CONVERT(date, FinishDate) >= #DATE)
)
BEGIN
Return 1
END
ELSE
BEGIN
Return 2
END

Add Hours to Current Date But it excludes the holidays and weekends

I have a task to create the T-SQL function to add the 12 hours with current date and time but it should not include any holidays/weekends.
ALTER FUNCTION [dbo].[GetNextWorkingDay_Custom] (#givenDate DATETIME)
RETURNS DATE
AS
BEGIN
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
DECLARE #DiffDate INT
DECLARE #workingDate DATETIME
IF (DATENAME(dw , #givenDate) = 'Friday')
BEGIN
SET #workingDate = DATEADD(day, 3, #givenDate)
END
ELSE IF (DATENAME(dw , #givenDate) = 'Saturday')
BEGIN
SET #workingDate = DATEADD(day, 2, #givenDate)
END
ELSE
BEGIN
SET #workingDate = DATEADD(day, 1, #givenDate)
END
SELECT #StartDate = START_DATE
,#EndDate = END_DATE
FROM special_time WHERE START_DATE = #workingDate AND IS_HOLIDAY = 1
-- Select count(*) from tblHolidays where holdate = #workingDate
while ((select count(*) from special_time WHERE START_DATE = #workingDate AND IS_HOLIDAY = 1) > 0)
begin
set #DiffDate = DATEDIFF(day,#StartDate,#EndDate)
set #workingDate = dateadd(dd,#DiffDate,#WorkingDate)
end
-- if adding a day makes it a Saturday, add 2 more to get to Monday (and test to make sure the week doesn't start with a holiday)
IF (DATENAME(dw , #workingDate) = 'Saturday')
BEGIN
SET #workingDate = DATEADD(day, 2, #workingDate)
END
RETURN #workingDate
END
Create a static dates lookup table (you can find many guides on how to do this via google, such as https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/) and then add a column that signifies whether or not that date is a working day or a holiday.
Your function is then as simple as:
select min(DateValue) as NextWorkingDay
from DatesLookupTable
where DateValue > #GivenDate
and WorkingDay = 1

Show 0 if null in query

I am running a sql query that is omitting the day if the return count is 0. I want my query to return the day and a 0 count if the the count is 0. Snare I have is that if 0 were sold for the day, the day is omitted from my return results.
SELECT ISNULL([day],0) As [day], COUNT(ISNULL(Sold,0)) As [Sold]
FROM productionInfo
You're drawing information from a single table, productionInfo. If productionInfo has no rows with that date information (because there are no widgets sold on that date), how does it know what dates to use?
You might want to look at using a Numbers Table to get a row for each day of the month/year, then join that to productionInfo so you have a day value available, even if there was no production that day.
This will give you a dates table:
CREATE FUNCTION dbo.DatesTable (#startDate DATETIME, #endDate DATETIME)
RETURNS #retTable TABLE (DateValue DATETIME)
AS
BEGIN
DECLARE #currentDate DATETIME
SET #currentDate = #startDate
WHILE (DATEDIFF(dd, #currentDate, #endDate) >= 0)
BEGIN
INSERT INTO #retTable VALUES (#currentDate)
SET #currentDate = DATEADD(dd, 1, #currentDate)
END
RETURN
END
Then your query will look like:
SELECT dt.DateValue AS [day], COUNT(Sold) AS [Sold]
FROM dbo.DatesTable('2-1-2014', '2-10-2014') dt
LEFT JOIN productionInfo pi ON pi.day = dt.DateValue
GROUP BY dt.DateValue

SQL Server Check if day does not fall on weekend and if so, iterate to a weekday

I am using SQL Server with t-Sql
I have the following code that checks to see if a date falls on a weekend
and if it does, it will iterate until the day falls on a weekday
Declare #ProDate as Date
set #ProDate = '08/05/12'
WHILE (DATEPART(DW, #ProDate) = 1 OR DATEPART(DW, #ProDate) = 7 )
BEGIN
set #ProDate = DATEADD(day, 1, #ProDate)
END
select #ProDate
The code seems to work. Wondering if I missed anything or if there is a better way to handle this.
This code is dependent on the setting of DATEFIRST in your system.
I'd add a SET DATEFIRST 7 before the date checks
Alternately, this avoids the while loop
declare #df int = ##Datefirst
set datefirst 1
select
case when DATEPART(DW, #ProDate)>=6 then
DATEADD(d, 8-DATEPART(DW, #ProDate), #prodate)
else #ProDate
end
set DATEFIRST #df
This code will work. It is almost identical to code that we use in a heavily used function.
The only suggestion that I might have is do you need to integrate a Holiday check? We have a Holiday table to store dates that need to be skipped as well.
Use below code to get next wrking date after excluding weekends and Holidays
Declare #AddDay as integer = 3
Declare #NextWorkingDate DateTime
Declare #StartDate DateTime = Cast(getdate() as date)
While #AddDay > 0
begin
Select #NextWorkingDate = #StartDate + #AddDay +
(datediff(wk, #StartDate, #StartDate+ #AddDay ) * 2) -- add weekend
--Exclude weekend
If datepart(dw,#NextWorkingDate ) = 1 or datepart(dw,#NextWorkingDate ) = 7 --Add 2 days if target date is either Saturday or Sunday
set #NextWorkingDate = #NextWorkingDate + 2
--Count no of holidays if falling within start date and nextwrking date
Select #AddDay = Count(*) from HolidayTable ST --Holiday list
where ST.OffDate between #StartDate+1 and #NextWorkingDate
Set #StartDate = #NextWorkingDate
End
Select #NextWorkingDate
USE below to exclude weekeends and Holiday
Declare #AddDay as integer = 3
Declare #NextWorkingDate DateTime
Declare #StartDate DateTime = Cast(getdate() as date)
While #AddDay > 0
begin
Select #NextWorkingDate = #StartDate + #AddDay +
(datediff(wk, #StartDate, #StartDate+ #AddDay ) * 2) -- add weekend
--Exclude weekend
If datepart(dw,#NextWorkingDate ) = 1 or datepart(dw,#NextWorkingDate ) = 7 --Add 2 days if target date is either Saturday or Sunday
set #NextWorkingDate = #NextWorkingDate + 2
--Count no of holidays if falling within Hold days/Deposit days
Select #AddDay = Count(*) from HolidayTable ST --Holiday list
where ST.OffDate between #StartDate+1 and #NextWorkingDate
Set #StartDate = #NextWorkingDate
End
Select #NextWorkingDate

Resources