Related
I have been wondering is there any operator/function in sql server to tell about weekday between given day.
Example :11-19-2016 to 11-29-2016 I want check if there is tuesday between that day?
Try This:
declare #start varchar(100)='11-19-2016'
declare #end varchar(100)='11-29-2016'
;with dateRange as
(
select date = dateadd(dd, 1, #start)
where dateadd(dd, 1, #start) < #end
union all
select dateadd(dd, 1, date)
from dateRange
where dateadd(dd, 1, date) < #end
)
select date,DATENAME(dw,CAST(DATEPART(m, GETDATE()) AS VARCHAR)
+ '/'+ CAST(DATEPART(d, date) AS VARCHAR)
+ '/'+ CAST(DATEPART(yy, getdate()) AS VARCHAR)) as 'Day'
from dateRange where (DATENAME(dw,CAST(DATEPART(m, GETDATE()) AS VARCHAR)
+ '/'+ CAST(DATEPART(d, date) AS VARCHAR)
+ '/'+ CAST(DATEPART(yy, getdate()) AS VARCHAR)))='Tuesday'
The query below uses a recursive query to unfold the date range.
Then uses DATEPART to select only the Tuesdays from it.
But one could also use DATENAME instead.
declare #StartDate DATE = '2016-11-19';
declare #EndDate DATE = '2016-11-29';
--SET DATEFIRST 7;
-- The dw for tuesday is 3 when ##datefirst = 7 (default setting)
-- Since it depends on a usersetting, lets calculate it anyway.
declare #TuesdayWeekday INT = (7-##datefirst + 2)%7+1;
;with DATES as
(
select #startdate as [Date]
union all
select dateadd(day, 1, [Date]) from DATES
where [Date] < #enddate
)
select [Date], datepart(dw,[Date]) as day_of_week, datename(dw,[Date]) as day_of_weekname
from DATES
where datepart(dw,[Date]) = #TuesdayWeekday;
My scenario is as below:
#StartDate = 13th of current month
#EndDate = 12th of next month.
I want to get all the date with the day-name for Mondays, Tuesdays, Wednesdays, Thursdays, Fridays, Saturdays and Sundays lying between the start and end date.
Try this:
declare #startDate datetime = '2016-01-13'
declare #endDate datetime = '2016-02-12'
;with dateRange as
(
select [Date] = dateadd(dd, 1, #startDate)
where dateadd(dd, 1, #startDate) < #endDate
union all
select dateadd(dd, 1, [Date])
from dateRange
where dateadd(dd, 1, [Date]) < #endDate
)
select [Date], datename(dw,[Date])
from dateRange
To count the number of each day as per your comment (this should be part of the question really), change the last part of James' answer to this:
select datename(dw,[Date]) as day_name, count([Date]) as number_days
from dateRange group by datename(dw,[Date]), datepart(DW,[Date])
order by datepart(DW,[Date]);
You can try something like this :
DECLARE #StartDate DATETIME
DECLARE #StartDateFixed DATETIME
DECLARE #EndDate DATETIME
DECLARE #NumberOfDays int
SET #StartDate = '2016/01/01'
SET #EndDate = '2016/01/02'
SET #NumberOfDays = DATEDIFF(DAY,#StartDate,#EndDate) + 1
SET #StartDateFixed = DATEADD(DD,-1,#StartDate)
SELECT WeekDay , COUNT(WeekDay)
FROM (
SELECT TOP (#NumberOfDays) WeekDay = DATENAME(DW , DATEADD(DAY,ROW_NUMBER() OVER(ORDER BY spt.name), #StartDateFixed))
FROM [master].[dbo].[spt_values] spt
) A
GROUP BY WeekDay
The output will be
WeekDay
------------------------------ -----------
Friday 1
Saturday 1
(2 row(s) affected)
In case if you need to get current and next date from date number specified such as 13 and 12
Current Month
DECLARE #cur_mont INT = (SELECT MONTH(GETDATE()))
Current Year
DECLARE #cur_year INT = (SELECT YEAR(GETDATE()))
Next Month
DECLARE #nxt_mont INT = (SELECT MONTH(DATEADD(month, 1, GETDATE())))
Next Month year (In case of December year change)
DECLARE #nxt_year INT = (SELECT YEAR(DATEADD(month, 1, GETDATE())))
Create start date
DECLARE #startDate DATETIME = (SELECT CAST(CAST(#cur_year AS varchar) + '-' + CAST(#cur_mont AS varchar) + '-' + CAST(13 AS varchar) AS DATETIME))
Create end date
DECLARE #endDate DATETIME = (SELECT CAST(CAST(#nxt_year AS varchar) + '-' + CAST(#nxt_mont AS varchar) + '-' + CAST(12 AS varchar) AS DATETIME))
Dates between start and end date
SELECT TOP (DATEDIFF(DAY, #startDate, #endDate) + 1)
DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, #startDate) AS Date,
DATENAME(DW, DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, #startDate)) AS Day
FROM sys.all_objects a CROSS JOIN sys.all_objects b;
DECLARE #dayStart int = 13, --The day of current month
#dayEnd int = 12, --The day of another month
#howManyMonth int = 1, --How many month to take
#dateStart date,
#dateEnd date
--Here we determine range of the dates
SELECT #dateStart = CONVERT (date,
CAST(DATEPART(Year,GETDATE()) as nvarchar(5))+ '-' +
CASE WHEN LEN(CAST(DATEPART(Month,GETDATE()) as nvarchar(5))) = 1
THEN '0'+CAST(DATEPART(Month,GETDATE()) as nvarchar(5))
ELSE CAST(DATEPART(Month,GETDATE()) as nvarchar(5)) END + '-' +
CAST (#dayStart as nvarchar(5))),
#dateEnd = CONVERT (date,
CAST(DATEPART(Year,DATEADD(Month,#howManyMonth,GETDATE())) as nvarchar(5))+ '-' +
CASE WHEN LEN(CAST(DATEPART(Month,DATEADD(Month,#howManyMonth,GETDATE())) as nvarchar(5))) = 1
THEN '0'+CAST(DATEPART(Month,DATEADD(Month,#howManyMonth,GETDATE())) as nvarchar(5))
ELSE CAST(DATEPART(Month,DATEADD(Month,#howManyMonth,GETDATE())) as nvarchar(5)) END + '-' +
CAST (#dayEnd as nvarchar(5)))
;WITH cte AS (
SELECT #dateStart as date_
UNION ALL
SELECT DATEADD(day,1,date_)
FROM cte
WHERE DATEADD(day,1,date_) <= #dateEnd
)
--Get results
SELECT DATENAME(WEEKDAY,date_) as [DayOfWeek],
COUNT(*) as [DaysCount]
FROM cte
GROUP BY DATEPART(WEEKDAY,date_),
DATENAME(WEEKDAY,date_)
ORDER BY DATEPART(WEEKDAY,date_)
OPTION (MAXRECURSION 0)
Output:
DayOfWeek DaysCount
----------- -----------
Sunday 4
Monday 4
Tuesday 4
Wednesday 5
Thursday 5
Friday 4
Saturday 4
(7 row(s) affected
I have a week number and year and i need to display "total for mm/dd/yy to mm/dd/yy in a row of my ssrs report. My week starts with Monday. For example if my week number is '2' and year is '2010' then I have to display "total for 01/04/2010 to 01/10/2010 in my ssrs column. how to do this?
Try this
declare #year char(4) = '2010'
declare #week int = 2
declare #fromdate datetime
declare #todate datetime
set #fromdate = DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + #year) + (#week-1), 7);
set #todate = DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + #year) + (#week-1), 6) ;
;WITH dates AS
(
SELECT CONVERT(datetime,#fromDate) as Date
UNION ALL
SELECT DATEADD(d,1,[Date])
FROM dates
WHERE DATE < #toDate
)
select * from dates
SQL Server has a DATEPART function which calculates the ordinal week number of a year. However, you have to call DATEFIRST before this to define which day of the week represents the start of the week. In your case, you have stated that the start of your week is Monday (i.e. 1).
SET DATEFIRST 1;
SELECT SUM([your data column])
FROM [your table]
WHERE DATEPART(WEEKNUM, [your date column])=[your week parameter]
AND DATEPART(YEAR, [your date column])=[your year parameter]
Your description is not american standard nor isoweek. Seems like a mix of those. I never heard of that as a standard. It is nearly isoweek. So that is what this answer is based on.
Calculating iso year is a bit tricky, you can read about it here:
This is the syntax you need:
DECLARE #year int = 2010
DECLARE #week int = 2
;WITH CTE AS
(
SELECT
dateadd(wk, datediff(wk, - #week * 7,
cast(cast(#year as char(4)) as datetime) - 5), 0) startofweek
)
SELECT
replace('total for ' + convert(char(10), startofweek, 110)
+ ' to ' + convert(char(10), dateadd(day, 6, startofweek) , 110), '-', '/')
FROM CTE
Result:
total for 01/11/2010 to 01/17/2010
Isoweek 2 in 2010 is 2010-01-11
Try setting DATEFIRST (https://msdn.microsoft.com/en-ie/library/ms181598.aspx)
SET DATEFIRST 7
declare #wk int
declare #yr int
declare #EndOfWeek as datetime
set #wk = 2
set #yr = 2010
SET #EndOfWeek = dateadd (week, #wk, dateadd (year, #yr-1900, 0)) + 1 - datepart(dw, dateadd (week, #wk, dateadd (year, #yr-1900, 0)) )
SELECT
replace('total for ' + convert(char(10), dateadd(day, -6, #EndOfWeek) , 110)
+ ' to ' + convert(char(10), #EndOfWeek, 110), '-', '/')
The result:
total for 01/04/2010 to 01/10/2010
I hope it helps:
declare #year char(4) = '2014'
declare #week int = 2
select dateadd(week,#week,convert(date,#year+'-01-01',121))
Change the date format appropriate for you from this list
SELECT
#begindate = dateadd(mm,-1,CAST(datepart(mm,getdate()) AS VARCHAR(2)) + '/15/' + CAST(datepart(YYYY,getdate() -1) AS varchar(4))),
#enddate = CAST(datepart(mm,getdate()) AS VARCHAR(2)) + '/14/' + CAST(datepart(YYYY,getdate() -1) AS varchar(4))
Right now this code returns the dates May 15th - June 14th. Those are the required dates that I need, but what I also need is for it to be in the year 2013, and this returns the year 2014. I've tried doing a dateadd(yyyy, -1) and it didn't work. So I was wondering if anyone knew how I would be able to get last years date.
If DateAdd didn't work, there must have been an error in your implementation. Try it like this after your existing code:
SET #begindate = dateadd(year, -1, #begindate);
SET #enddate = dateadd(year, -1, #enddate)
declare #begindate datetime
declare #enddate datetime
set #begindate = dateadd(mm,-1,CAST(datepart(mm,getdate()) AS VARCHAR(2)) + '/15/' + CAST(datepart(YYYY, getdate()) - 1 AS varchar(4)))
set #enddate = CAST(datepart(mm,getdate() ) AS VARCHAR(2)) + '/14/' + CAST(datepart(YYYY, getdate()) - 1 AS varchar(4))
select #begindate
union all
select #enddate
Instead of working with strings you can use date variables and date arithmetic:
declare #lastyear date=dateadd(yy,-1,cast(getdate() as date))
declare #currentMonth date=dateadd(d,-day(#lastyear),#lastyear)
declare #prevMonth date=dateadd(m,-1,#currentMonth)
select #lastyear,DATEADD(d,14,#currentMonth),DATEADD(d,15,#prevMonth)
In SQL Server 2012 it's even easier because you can use the DATEFROMPARTS function to construct a new date from its parts.
Just want to select all dates between cureent date and first day of month . I want to use fill all dates in a temp table
declare #temp table
(
ddate datetime
)
I have tried with with cte and i don't want to use while loop becuase i want to avoid while in stored procedure .
For example as today is 11-oct-2012
so temp table should have 11 rows starting from 1-oct-2012 to 11-oct-2012
Try this
DECLARE #startDate DATE=CAST(MONTH(GETDATE()) AS VARCHAR) + '/' + '01/' + + CAST(YEAR(GETDATE()) AS VARCHAR) -- mm/dd/yyyy
DECLARE #endDate DATE=GETDATE() -- mm/dd/yyyy
SELECT [Date] = DATEADD(Day,Number,#startDate)
FROM master..spt_values
WHERE Type='P'
AND DATEADD(day,Number,#startDate) <= #endDate
OR
DECLARE #startDate DATETIME=CAST(MONTH(GETDATE()) AS VARCHAR) + '/' + '01/' + + CAST(YEAR(GETDATE()) AS VARCHAR) -- mm/dd/yyyy
DECLARE #endDate DATETIME= GETDATE() -- mm/dd/yyyy
;WITH Calender AS
(
SELECT #startDate AS CalanderDate
UNION ALL
SELECT CalanderDate + 1 FROM Calender
WHERE CalanderDate + 1 <= #endDate
)
SELECT [Date] = CONVERT(VARCHAR(10),CalanderDate,25)
FROM Calender
OPTION (MAXRECURSION 0)
declare #temp table (ddate datetime);
insert #temp
select DATEDIFF(d,0,GetDate()-Number)
from master..spt_values
where type='p' and number < DatePart(d,Getdate())
order by 1;
use current_date add days of every the generated series to the days, the series could from the first day of the month subtract current_day to 0, such today 02 Jun, the series could be (-1, 0).
Try the following code:
DECLARE #startDate DATETIME=CAST(MONTH(GETDATE()) AS VARCHAR) + '/' + '01/' + + CAST(YEAR(GETDATE()) AS VARCHAR) -- mm/dd/yyyy
DECLARE #endDate DATETIME= CAST(MONTH(GETDATE()) AS VARCHAR) + '/' + '31/' + + CAST(YEAR(GETDATE()) AS VARCHAR) -- mm/dd/yyyy
;WITH Calender AS
(
SELECT #startDate AS CalanderDate
UNION ALL
SELECT CalanderDate + 1 FROM Calender
WHERE CalanderDate + 1 <= #endDate
)
SELECT [Date] = CONVERT(VARCHAR(10),CalanderDate,25)
FROM Calender
OPTION (MAXRECURSION 0)