How to get days from date to date in SQL Server? - sql-server

In SQL Server, I want to get days from date to date. Example: from 2015/12/28 to 2016/01/02, the result as
2015/12/28
2015/12/29
2015/12/30
2015/12/31
2016/01/01
2016/01/02
DECLARE #STARTDATE DATETIME = '2015-12-28'
DECLARE #ENDDATE DATETIME = '2016-01-02'
SELECT BETWEEN #STARTDATE AND #ENDDATE AS DAYS

Use CTE
DECLARE #STARTDATE DATE = '2015-12-28'
DECLARE #ENDDATE DATE = '2016-01-02'
;WITH CTE AS
(
SELECT #STARTDATE As dt
UNION ALL
SELECT DATEADD(D,1,dt) AS dt
FROM CTE
WHERE dt < #ENDDATE
)
SELECT * FROM CTE

You could build a calendar table, which would probably come in handy down the road. Or you could use a loop.
DECLARE #ENDDATE DATETIME = '2016-01-02'
DECLARE #DAY DATETIME = '2015-12-28'
WHILE #Day <= #ENDDATE
BEGIN
SELECT #DAY
SET #DAY = DATEADD(DD,1,#DAY)
END
Or for all of the days in one result set:
DECLARE #ENDDATE DATETIME = '2016-01-02'
DECLARE #DAY DATETIME = '2015-12-28'
DECLARE #TABLE TABLE (DATE DATETIME)
WHILE #Day <= #ENDDATE
BEGIN
INSERT #TABLE
VALUES (#DAY)
SET #DAY = DATEADD(DD,1,#DAY)
END
SELECT *
FROM #TABLE

You can specify the dates in your WHERE clause. For example, WHERE date >=#STARTDATE AND date <=#ENDDATE. That should return the full date in your results.

using Numbers table
select dateadd(day,n,startdate)
from numbers
where dateadd(day,n,startdate)<=enddate
order by n

Related

Create a function that return total Working days between two dates

I would like to create a function in SQL Server that would return the no of working days after checking the day from the dimension table dimcalender which has all the working days from 2020 up until 2040
My Code:
Create FUNCTION [udf_WorkingDays]
(
-- Add the parameters for the function here
#StartDate DATETIME,
#EndDate DATETIME
)
RETURNS INT
AS
BEGIN
DECLARE #TotalDays INT
SET #StartDate = '2022/06/01'
SET #EndDate = '2022/06/07'
SET #TotalDays = 0
--SET #TotalDays =(
WHILE (#StartDate <= #EndDate)
BEGIN
sum(select WorkingDay
FROM [XS].[dimCalendar]
where [Date] >= #StartDate
and [Date] <= #EndDate)
set #StartDate = DATEADD(day, 1, #StartDate)
--set #TotalDays = dss;)
END;
RETURN #TotalDays
END;
[dimCalendar] is where all UK working days are recorded.
WorkingDay is just a flag to say 0,1 (if its a working day or not.)
TotalDays is a variable that will have total no. of working days that will be returned.
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
DECLARE #TotalDays INT
DECLARE #DDays INT
SET #StartDate = '2022/06/01'
SET #EndDate = '2022/06/06'
SET #TotalDays = 0
SET #TotalDays = (
SELECT a.toti
FROM (
SELECT SUM(WorkingDay) AS toti
FROM [dimCalendar]
WHERE [Date] >= #StartDate
AND [Date] <= #EndDate
) AS a
)
RETURN #TotalDays;

sql two monday night between

I have a problem about sql query. Now I have GETDATE() FOR example today is wednesday, I need to have date between tho monday nights. and GETDATE() will be in this two date
Example today is thursday 18.05.2017 I want date between 15.05.2017 and 22.05.2017
I couldn't find any solution. How can I write it in where statement in query.
SELECT * FROM MATCHES
WHERE ...
Thanks in advance
To receive first monday:
SELECT DATEADD(ww, DATEDIFF(ww,0,GETDATE()), 0)
and second one:
SELECT DATEADD(ww, DATEDIFF(ww,0,GETDATE()) + 1, 0)
http://joelabrahamsson.com/getting-the-first-day-in-a-week-with-t-sql/
also
Get first day of week in SQL Server
here is the solution
firstly create a calendar table then
declare #startDate datetime = dateadd(week, datediff(week, 0, getdate()), 0);
declare #endDate datetime = DATEADD(DAYS,7,#startDate)
SELECT Date
FROM dbo.Calendar
WHERE Date >= #startDate
AND Date < #endDate ;
Create a Calendar Table if not exists
IF EXISTS (SELECT * FROM information_schema.tables WHERE Table_Name =
'Calendar' AND Table_Type = 'BASE TABLE')
BEGIN
DROP TABLE [Calendar]
END
CREATE TABLE [Calendar]
(
[CalendarDate] DATETIME
)
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #StartDate = GETDATE()
SET #EndDate = DATEADD(d, 365, #StartDate)
WHILE #StartDate <= #EndDate
BEGIN
INSERT INTO [Calendar]
(
CalendarDate
)
SELECT
#StartDate
SET #StartDate = DATEADD(dd, 1, #StartDate)
END
Then, Use below query to get the output
declare #start datetime = dateadd(week, datediff(week, 0, getdate()), 0);
declare #end datetime = DATEADD(DAY,8,#start)
SELECT [CalendarDate]
FROM Calendar
WHERE CalendarDate BETWEEN #start AND #end

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

How can I list all dates between two date parameters in SQL

How can I list all dates between two date parameters in SQL Server, without creating a stored procedure, calendar table or recursive function?
There's always the recursive CTE option:
DECLARE #STARTDATE DATETIME
DECLARE #ENDDATE DATETIME
SET #STARTDATE = '2015-01-01'
SET #ENDDATE = '2015-12-31'
;WITH DATE_RANGE (DATES) AS (
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, #STARTDATE), 0)
UNION ALL SELECT DATEADD(DAY, 1, DATES)
FROM DATE_RANGE
WHERE DATEADD(DAY, 1, DATES) <= #ENDDATE)
SELECT DATES
FROM DATE_RANGE
OPTION (MAXRECURSION 0)
Be sure to use the MAXRECURSION option, or your results will be limited to 100 as default.
This uses Row_Number on the spt_values table in Master database to create a list of years, months and dates within the date range.
This is then built into a datetime field, and filtered to only return dates within the date parameters entered.
Very quick to execute and returns 500 years worth of dates (182987 days) in less than 1 second.
Declare #DateFrom datetime = '2000-01-01'
declare #DateTo datetime = '2500-12-31'
Select
*
From
(Select
CAST(CAST(years.Year AS varchar) + '-' + CAST(Months.Month AS varchar) + '-' + CAST(Days.Day AS varchar) AS DATETIME) as Date
From
(select row_number() over(order by number) as Year from master.dbo.spt_values) as Years
join (select row_number() over(order by number) as Month from master.dbo.spt_values) as Months on 1 = 1
join (select row_number() over(order by number) as Day from master.dbo.spt_values) as Days on 1 = 1
Where
Years.Year between datepart(year,#DateFrom) and datepart(year,#DateTo)
and Months.Month between 1 and 12
and
Days.Day between 1 and datepart(day,dateadd(day,-1,dateadd(month,1,(CAST(CAST(Years.Year AS varchar)+'-' + CAST(Months.Month AS varchar) + '-01' AS DATETIME)))))
) as Dates
Where Dates.Date between #DateFrom and #DateTo
order by 1
Following will be a solution for YOU
DECLARE #DATE1 DATE
DECLARE #DATE2 DATE
SET #DATE1 ='20020101'
SET #DATE2 = '20020311'
SELECT #DATE1 as t
into #FromDate
DECLARE cur CURSOR FOR
SELECT t FROM #FromDate
OPEN cur
FETCH NEXT FROM cur INTO #DATE1
WHILE(##FETCH_STATUS=0)
BEGIN
IF(#DATE1<=#DATE2)
INSERT INTO #FromDate
VALUES(DATEADD(DAY,1,#DATE1))
FETCH NEXT FROM cur INTO #DATE1
END
CLOSE cur
DEALLOCATE cur;
SELECT t FROM #FromDate;
DROP TABLE #FromDate;
Simple result.
DECLARE #DATE1 DATE
DECLARE #DATE2 DATE
SET #DATE1 ='20020101'
SET #DATE2 = '20020311'
WHILE(#DATE1<=#DATE2)
Begin
PRINT #DATE1
set #DATE1 = DATEADD(dd,1,#DATE1)
END

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

Resources