T-SQL Date Difference for WeekDays only - sql-server

I am trying to get the date difference in a given date excluding the week days.
Here is what I have:
SELECT DATEADD (w, -4, GETDATE())
This returns 2013-05-04 19:01:53.170, which means that it also counts weekends.
Same for
SELECT DATEADD (dw, -4, GETDATE())
Any help will be appreciated.
Thanks in advance.

I'm using these functions that return the non-weekend seconds between two dates:
CREATE FUNCTION [dbo].[DateDiff_NoWeekends](
#date1 DATETIME,
#date2 DATETIME
)
RETURNS INT AS BEGIN
DECLARE #retValue INT
SET #date1 = dbo.__CorrectDate(#date1, 1)
SET #date2 = dbo.__CorrectDate(#date2, 0)
IF (#date1 >= #date2)
SET #retValue = 0
ELSE BEGIN
DECLARE #days INT, #weekday INT
SET #days = DATEDIFF(d, #date1, #date2)
SET #weekday = DATEPART(dw, #date1) - 1
SET #retValue = DATEDIFF(s, #date1, #date2) - 2 * 24 * 3600 * ((#days + #weekday) / 7)
END
RETURN #retValue
END
GO
CREATE FUNCTION [dbo].[__CorrectDate](
#date DATETIME,
#forward INT
)
RETURNS DATETIME AS BEGIN
IF (DATEPART(dw, #date) > 5) BEGIN
IF (#forward = 1) BEGIN
SET #date = #date + (8 - DATEPART(dw, #date))
SET #date = DateAdd(Hour, (8 - DatePart(Hour, #date)), #date)
END ELSE BEGIN
SET #date = #date - (DATEPART(dw, #date)- 5)
SET #date = DateAdd(Hour, (18 - DatePart(Hour, #date)), #date)
END
SET #date = DateAdd(Minute, -DatePart(Minute, #date), #date)
SET #date = DateAdd(Second, -DatePart(Second, #date), #date)
END
RETURN #date
END
Here's a sql-fiddle demo for all non-weekend days in april (22).
SELECT [no weekend days in april] =
(dbo.DateDiff_NoWeekends('2013-04-01','2013-05-01')
/ 3600 / 24)

The query below gives the difference for week days alone , Ie counts the no od days between two days and subtracts the no of weekend days ,
DECLARE #StartDate DATETIME,
#EndDate DATETIME
SELECT #StartDate = '01-July-2008',
#EndDate = '30-July-2008'
;WITH DATE (Date1)
AS (
SELECT DATEADD(DAY, DATEDIFF(DAY, '19000101', #StartDate), '19000101')
UNION ALL
SELECT DATEADD(DAY, 1, Date1)
FROM DATE
WHERE Date1 < #EndDate
)
SELECT count(*) -
(
SELECT count(*)
--CONVERT(VARCHAR(15),d1.DATE1 ,110) as [Working Date],
--DATENAME(weekday, d1.Date1) [Working Day]
from DATE d1 where (DATENAME(weekday, d1.Date1)) in ('Saturday','Sunday')
)
--CONVERT(VARCHAR(15),d1.DATE1 ,110) as [Working Date],
--DATENAME(weekday, d1.Date1) [Working Day]
from DATE d1 where (DATENAME(weekday, d1.Date1)) not in ('Saturday','Sunday')
please let me know for any clarifications

Maybe I am still missing some full testing, but this works for me too: take the difference in days and then subtract 2 days for each weekend
DateDiff(d, d1, d2) - 2*DateDiff(wk, d1, d2)
Could be put in a function as well

Related

How to remove saturday and sunday in a month in sql server

for example:
--fromdate         todate
--2020/10/1       2020/11/01
Output should be like:
--Days           dayname
-------      ---------------
--2020/10/1  Monday
.. ..
You can use DATENAME to get the WEEKDAY and filter by it:
DATENAME ( WEEKDAY , my_date )
Something like this (the code for generating days is from here)
declare #dt datetime, #dtEnd datetime
set #dt = '2020/10/1'
set #dtEnd = '2020/11/01'
select dateadd(day, number, #dt)
,DATENAME ( WEEKDAY , dateadd(day, number, #dt) )
from
(select number from master.dbo.spt_values
where [type] = 'P'
) n
where dateadd(day, number, #dt) < #dtEnd
AND DATENAME ( WEEKDAY , dateadd(day, number, #dt) ) NOT IN ('Saturday', 'Sunday')
I think this query works well.
declare #result table
(
Days varchar(10),
DayName varchar(20)
)
declare #fromDate date = '2020/10/01'
declare #toDate date = '2020/11/01'
while #fromDate <= #toDate
begin
if DATENAME(weekday, #fromDate) not in ('Saturday', 'Sunday')
begin
insert into #result(Days, DayName)
values(#fromDate, DATENAME(weekday, #fromDate))
end
set #fromDate = DATEADD(day, 1, #fromDate)
end
select *
from #result

Generate a stock position report as at each month with a date variable set at a specific month

I am trying to generate a stock position report as at each month. within my query i have a date variable set at a specific month:
declare #date datetime = CONVERT(DATETIME, '2019-08-13 00:00:00', 121)
declare #lastmonth datetime = (select cast(dateadd(day, -day(getdate()), getdate()) as date))
declare #m int = 0
--**my aim is to ensure that #date = #lastmonth**
while #date<= #lastmonth
Begin
set #m = #m + 1
while #m < 12
Begin
set #date = (select dateadd(mm, #m, #date))
End
End
select

Retrieve date from year, week number, day name in SQL Server 2012

Thanks for all for reading my questions, I have fallen a big problem to retrieve date from SQL Server 2012 by providing year, week number and day name.
Suppose I have
Year = 2016
Week number = 1
Day Name ='FRI'
First day of week='SUN'
Expected result:
01-01-2016
How can I do that?
EDIT: I have found similar solution from here but I have no month name.
My suggestion is based on the solution to the question in the link you provided.
Basically, I've created a calendar that holds the dates since January 1st of the year till #x weeks after that, and then queried that calendar:
-- provided data:
DECLARE #Year int = 2016,
#WeekNumber int = 1,
#DayName char(3) = 'Fri';
-- Calculate start date and end date
DECLARE #StartDate date,
#EndDate date;
SELECT #StartDate = CAST('01-01-'+ CAST(#Year as char(4)) as date),
#EndDate = DATEADD(WEEK, #WeekNumber, #StartDate)
-- Create the calendar
;WITH CTE AS
(
SELECT #StartDate as TheDate
UNION ALL
SELECT DATEADD(DAY, 1, TheDate)
FROM CTE
WHERE DATEADD(DAY, 1, TheDate) <= #EndDate
)
-- Finally, query the calendar:
SELECT TheDate
FROM CTE
WHERE DATEPART(WEEK, TheDate) = #WeekNumber
AND YEAR(TheDate) = #Year
AND DATENAME(WEEKDAY, TheDate) LIKE #DayName + '%'
OPTION(MAXRECURSION 0)
results:
TheDate
----------
2016-01-01
Note: This solution will return no rows if the day you specify is mon, since the first week of 2016 starts on Friday.
TRY THIS
DECLARE #Year varchar(4)
DECLARE #WeekDayday varchar(10)
DECLARE #WeekNumber int
SET #Year ='2016'
SET #WeekDayday ='fri'
SET #WeekNumber =1
--used to solve
DECLARE #StartDate datetime
,#EndDate datetime
,#FirstWeek int
SET #StartDate='01-01-'+' '+#Year
SET #EndDate=#StartDate+38
SET #FirstWeek=DATENAME(week,#StartDate)-1
;with AllDates AS
(
SELECT #StartDate AS DateOf, DATENAME(week,#StartDate)-#FirstWeek AS WeekOf, DATENAME(weekday,#StartDate) AS WeekDayOf
UNION ALL
SELECT DateOf+1, DATENAME(week,DateOf+1)-#FirstWeek AS WeekOf, DATENAME(weekday,DateOf+1) AS WeekDayOf
FROM AllDates
WHERE DateOf<#EndDate
)
SELECT
DateOf
FROM AllDates
WHERE WeekOf=#WeekNumber AND WeekDayOf LIKE #WeekDayday+'%'
ORDER BY DateOf
How about improve that answer by evaluate month name by week number:
--given info
DECLARE #Year varchar(4);
DECLARE #MonthName varchar(10);
DECLARE #WeekDayday varchar(10);
DECLARE #WeekNumber int;
SET #Year = '2016';
SET #WeekDayday = 'Tue';
set #WeekNumber = 46;
-- get month number by week
declare #w int = 0;
declare #m int = 1;
while (#w <= #WeekNumber and #m < 13) begin
set #w = datepart(wk, datefromparts(#year, #m, 1));
if (#w <= #WeekNumber and #m < 13) begin
set #m = #m + 1;
end;
end;
set #m = #m -1;
-- get month name
set #MonthName = left(DateName(month ,DateAdd(month ,#m ,0 ) - 1), 3);
--used to solve
DECLARE #StartDate datetime
,#EndDate datetime
,#FirstWeek int
SET #StartDate='01 '+#MonthName+' '+#Year
SET #EndDate=#StartDate+38
SET #FirstWeek=DATENAME(week,#StartDate)-1
;with AllDates AS
(
SELECT #StartDate AS DateOf, DATENAME(week,#StartDate)-#FirstWeek AS WeekOf, DATENAME(weekday,#StartDate) AS WeekDayOf
UNION ALL
SELECT DateOf+1, DATENAME(week,DateOf+1)-#FirstWeek AS WeekOf, DATENAME(weekday,DateOf+1) AS WeekDayOf
FROM AllDates
WHERE DateOf<#EndDate
)
SELECT
DateOf ,WeekOf ,WeekDayOf
FROM AllDates
WHERE datepart(wk, DateOf) = #WeekNumber AND WeekDayOf LIKE #WeekDayday+'%'
ORDER BY DateOf

Find Mondays between 2 dates

I need to display dates of all Mondays in the given date range.
For example, if my start date is 01/05/2015 and end date is 31/05/2015, I need to show
04/05/2015
11/05/2015
18/05/2015
25/05/2015
How is it possible?
This procedure is independent from regions and languages.
Please note the first line with SET DATEFIRST 1.
SET DATEFIRST 1; -- First day of the week is set to monday
DECLARE #DateFrom DateTime ='20150601', #DateTo DateTime = '20150630' ;
WITH CTE(dt)
AS
(
SELECT #DateFrom
UNION ALL
SELECT DATEADD(d, 1, dt) FROM CTE
WHERE dt < #DateTo
)
SELECT dt FROM CTE where datepart ("dw", dt) = 1;
Using a CTE it is possible this way..
DECLARE #DateFrom DateTime ='2015-05-01',
#DateTo DateTime = '2015-05-31'
;WITH CTE(dt)
AS
(
SELECT #DateFrom
UNION ALL
SELECT DATEADD(d, 1, dt) FROM CTE
WHERE dt < #DateTo
)
SELECT 'Monday', dt FROM CTE
WHERE DATENAME(dw, dt) In ('Monday')
Refer: Select dates of a day between two dates.
SELECT [Day],[Dt] FROM dbo.fnGetDatesforAday('7/1/2008','8/31/2008','Sunday')
CREATE FUNCTION fnGetDatesforAday
(
-- Add the parameters for the function here
#DtFrom DATETIME,
#DtTo DATETIME,
#DayName VARCHAR(12)
)
RETURNS #DateList TABLE ([Day] varchar(20),Dt datetime)
AS
BEGIN
IF NOT (#DayName = 'Monday' OR #DayName = 'Sunday' OR #DayName = 'Tuesday' OR #DayName = 'Wednesday' OR #DayName = 'Thursday' OR #DayName = 'Friday' OR #DayName = 'Saturday')
BEGIN
--Error Insert the error message and return
INSERT INTO #DateList
SELECT 'Invalid Day',NULL AS DAT
RETURN
END
DECLARE #TotDays INT
DECLARE #CNT INT
SET #TotDays = DATEDIFF(DD,#DTFROM,#DTTO)-- [NO OF DAYS between two dates]
SET #CNT = 0
WHILE #TotDays >= #CNT -- repeat for all days
BEGIN
-- Pick each single day and check for the day needed
IF DATENAME(DW, (#DTTO - #CNT)) = #DAYNAME
BEGIN
INSERT INTO #DateList
SELECT #DAYNAME,(#DTTO - #CNT) AS DAT
END
SET #CNT = #CNT + 1
END
RETURN
END
SET DATEFIRST 7; -- Set's sunday as first day of week, won't work otherwise
DECLARE #StartDate DATE = '06/01/2015'
DECLARE #EndDate DATETIME = '06/30/2015'
DECLARE #TableOfDates TABLE(DateValue DATETIME)
DECLARE #CurrentDate DATETIME
SET #CurrentDate = #startDate
WHILE #CurrentDate <= #endDate
BEGIN
INSERT INTO #TableOfDates(DateValue) VALUES (#CurrentDate)
SET #CurrentDate = DATEADD(DAY, 1, #CurrentDate)
END
SELECT * FROM #TableOfDates WHERE DATEPART(weekday,Datevalue) = 2

Find out date difference in SQL Server

I have from date and to date in my table, I want to know total number of days between two dates without sunday, in SQL Server 2008.
give me a query..
Accept my question...
OK, so work out the total number of days, subtract the total number of weeks, and a fiddle factor for the case where the from date is a Sunday:
SELECT
DATEDIFF(dd, FromDate, ToDate)
-DATEDIFF(wk, FromDate, ToDate)
-(CASE WHEN DATEPART(dw, FromDate) = 1 THEN 1 ELSE 0 END)
try to use this as an example and work it..
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #StartDate = '2008/10/01'
SET #EndDate = '2008/10/31'
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)
You could do this with a CTE, and this couuld easily be turned into a scalar function:
DECLARE #startDate DATETIME = '2011-09-01'
DECLARE #endDate DATETIME = '2011-09-23'
;WITH DateRange (date) AS
(
SELECT #startDate
UNION ALL
SELECT Date+1
FROM DateRange
WHERE date<#endDate
)
SELECT COUNT(*) FROM DateRange WHERE DATENAME(dw,Date) != 'Sunday'
Returns 20 which is the number of days this month so far which are not sundays.
Here's an equivalent function which can be used:
CREATE FUNCTION dbo.NumberOfDaysExcludingSunday(
#startDate DATETIME,
#endDate DATETIME
) RETURNS INT AS
BEGIN
DECLARE #rtn INT
;WITH DateRange (date) AS
(
SELECT #startDate
UNION ALL
SELECT Date+1
FROM DateRange
WHERE date<#endDate
)
SELECT #rtn = COUNT(*) FROM DateRange WHERE DATENAME(dw,Date) != 'Sunday'
RETURN #rtn
END
Usage:
SELECT dbo.NumberOfDaysExcludingSunday(startDate,endDate)
FROM myTable

Resources