Date Range of the x-th week in SQL Server? - sql-server

I know the year and the index of the week, i.e. 2014, the 5th week. how can I find out the starting and ending date of this week in SQL Server? I do not really care whether the week starting with Monday or Sunday.
In mySQL, it has a MakeDate which may be able to do this. Is there an existing way to do this in SQL Server?
Thanks

Try this.
DECLARE #date DATE='2014-01-01'
SELECT Dateadd(dd, -( Datepart(dw, Dateadd(wk, 5, #date) - 1) ), Dateadd(wk, 5, #date)) [WeekStart],
Dateadd(dd, 7 - ( Datepart(dw, Dateadd(wk, 5, #date)) ), Dateadd(wk, 5, #date)) [WeekEnd]

SELECT
dateadd(wk,5,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)) as firstdayof5thweek2014,
dateadd(dd,6,dateadd(wk,5,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0))) as lastdayof5thweek2014
SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0) ==>gives you start day of the current year
SELECT dateadd(wk,5,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)) ==> On top add 5 weeks to get the start date of 5th week in 2014
SELECT dateadd(dd,6,dateadd(wk,5,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0))) ==> On top add 6 days to get the last date of 5th week in 2014

Related

How to get data of last 3 months from sql table

I have some date range values from which I want to fetch last 3 month details. How can I fetch the last 3 month details?
You can try like this, Put your appropriate date column in this query.
SELECT *
FROM TABLE_NAME
WHERE DATEADD(MONTH, -3, GETDATE()) between txtFromDate and txtToDate
you can check against last 90 days.
SELECT *
FROM TABLE_NAME
WHERE DATEADD(DAY, -90, GETDATE()) between txtFromDate and txtToDate
this will gives you the last 3 month date (from 1st of the month)
WHERE date_column >= DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 3, 0)
you have 3 date column there . . not sure which one you want use as reference

Dates between 18 and 9 months ago but from beginning to end of relevant months

I have a query that I thought I had cracked to return all records where the start date is between 18 and 9 months ago but I want all of the records for the month 18 months ago from the 1st of the month and all of the records for the month 9 months ago to the end of the month as well as the records in between.
At the moment my WHERE clause contains:
WHERE startdate BETWEEN
DATEADD(DAY, - (DAY(DATEADD(MONTH, 1, GETDATE())) - 18), DATEADD(MONTH, - 18, GETDATE()))
AND DATEADD(DAY, - (DAY(DATEADD(MONTH, 1, GETDATE())) - 9), DATEADD(MONTH, - 9, GETDATE())
But it is pulling all records where start date is between 18 and 9 months ago to the exact date today and is not going back to the start of the month or completing the end month. Please could you advise where I have gone wrong. I am sure it is something really simple but I have gone bracket blind now I think.
You can use DateAdd and DateDiff to get the first day of the month, like shown in this answer.
From this it's fairly simple to do something like this:
WHERE StartDate >= DATEADD(month, -18, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
AND StartDate < DATEADD(month, -8, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
You can use new SQL EMONTH() end of month function
For the first of month, you can add 1 day to the previous month's end of month

SQL Server - Finding the first day of the week

I've been looking around for a chunk of code to find the first day of the current week, and everywhere I look I see this:
DATEADD(WK, DATEDIFF(WK,0,GETDATE()),0)
Every place says this is the code I'm looking for.
The problem with this piece of code is that if you run it for Sunday it chooses the following Monday.
If I run:
SELECT GetDate() , DATEADD(WK, DATEDIFF(WK,0,GETDATE()),0)
Results for today (Tuesday):
2013-05-14 09:36:39.650................2013-05-13 00:00:00.000
This is correct, it chooses Monday the 13th.
If I run:
SELECT GetDate()-1 , DATEADD(WK, DATEDIFF(WK,0,GETDATE()-1),0)
Results for yesterday (Monday):
2013-05-13 09:38:57.950................2013-05-13 00:00:00.000
This is correct, it chooses Monday the 13th.
If I run:
SELECT GetDate()-2 , DATEADD(WK, DATEDIFF(WK,0,GETDATE()-2),0)
Results for the 12th (Sunday):
2013-05-12 09:40:14.817................2013-05-13 00:00:00.000
This is NOT correct, it chooses Monday the 13th when it should choose the previous Monday, the 6th.
Can anyone illuminate me as to what's going in here? I find it hard to believe that no one has pointed out that this doesn't work, so I'm wondering what I'm missing.
It is DATEDIFF that returns the "incorrect" difference of weeks, which in the end results in the wrong Monday. And that is because DATEDIFF(WEEK, ...) doesn't respect the DATEFIRST setting, which I'm assuming you have set to 1 (Monday), and instead always considers the week crossing to be from Saturday to Sunday, or, in other words, it unconditionally considers Sunday to be the first day of the week in this context.
As for an explanation for that, so far I haven't been able to find an official one, but I believe this must have something to do with the DATEDIFF function being one of those SQL Server treats as always deterministic. Apparently, if DATEDIFF(WEEK, ...) relied on the DATEFIRST, it could no longer be considered always deterministic, which I can only guess wasn't how the developers of SQL Server wanted it.
To find the first day of the week's date, I would (and most often do actually) use the first suggestion in #Jasmina Shevchenko's answer:
DATEADD(DAY, 1 - DATEPART(WEEKDAY, #Date), #Date)
DATEPART does respect the DATEFIRST setting and (most likely as a result) it is absent from the list of always deterministic functions.
Try this one -
SET DATEFIRST 1
DECLARE #Date DATETIME
SELECT #Date = GETDATE()
SELECT CAST(DATEADD(DAY, 1 - DATEPART(WEEKDAY, #Date), #Date) AS DATE)
SELECT CAST(#Date - 2 AS DATE), CAST(DATEADD(WK, DATEDIFF(WK, 0, #Date-2), 0) AS DATE)
Results:
---------- ----------
2013-05-12 2013-05-13
SQL Server has a SET DATEFIRST function which allows you to tell it what the first day of the week should be. SET DATEFIRST = 1 tells it to consider Monday as the first day of the week. You should check what the server's default setting is via ##DATEFIRST. Or you could simply change it at the start of your query.
Some references:
MSDN
Similar Question
That worked for me like a charm:
Setting moday as first day of the week without changing DATEFIRST variable:
-- FirstDayWeek
select dateadd(dd,(datepart(dw, case datepart(dw, [yourDate]) when 1 then dateadd(dd,-1,[yourDate]) else [yourDate] end) * -1) + 2, case datepart(dw, [yourDate]) when 1 then dateadd(dd,-1,[yourDate]) else [yourDate] end) as FirstDayWeek;
-- LastDayWeek
select dateadd(dd, (case datepart(dw, [yourDate]) when 1 then datepart(dw, dateadd(dd,-1,[yourDate])) else datepart(dw, [yourDate]) end * -1) + 8, case datepart(dw, [yourDate]) when 1 then dateadd(dd,-1,[yourDate]) else [yourDate] end) as LastDayWeek;
Setting sunday as fist day of the week without changing DATEFIRST variable
select convert(varchar(50), dateadd(dd, (datepart(dw, [yourDate]) * -1) + 2, [yourDate]), 103) as FirstDayWeek, convert(varchar(50), dateadd(dd, (datepart(dw, [yourDate]) * -1) + 8, [yourDate]), 103) as LastDayWeek;
You can change [yourDate] by GETDATE() for testing

How to select the beginning of the following April in SQL Server?

Could you please help me select a date which is the beginning of a particular following month, e.g. April?
For example, if it is Jan 08 2013, it should select April 01 2013, but if it is June 08 2013, it should select April 01 2014.
Thanks.
I would create a calendar table, then you can simply do something like this:
select
min([Date])
from
dbo.Calendar
where
MonthNumber = 4 and
DayNumber = 1 and
[Date] > getdate()
Querying a calendar table is usually clearer, simpler and more flexible than using date functions. You might also want to consider what happens if today is April 1: do you want today's date, or next year's?
If you're interested in April 1 because it's the start of a financial year, you can add that information to your calendar table directly:
select
min([Date])
from
dbo.Calendar
where
IsStartOfFinancialYear = 0x1 and
[Date] > getdate()
Use the DATEADD and the DATEPART function, like this short example:
DECLARE #Date Datetime
SET #Date = '2013.01.08 00:00:00'
SELECT DATEADD(year,
CASE WHEN DATEPART(month, #Date) < 4
THEN 0
ELSE 1 END,
DATEADD(day, -DATEPART(day, #Date) + 1,
DATEADD(month, -DATEPART(month, #Date) + 4, #Date)))

SQL Server - Get first date in a week, given the week number?

I've got a query (for use in bug tracker.net) that calculates the number of bugs by week by status. But the query returns the week number, what I really want is the first date of the week
select datepart(wk, DateAdd(day, 0, DateDiff(day, 0, bg_reported_date)))
as [week], bg_status , st_name as [status], count(*) as [count]
from bugs inner join statuses on bg_status = st_id
group by datepart(wk, DateAdd(day, 0, DateDiff(day, 0, bg_reported_date))),
bg_status, st_name
order by [week], bg_status
The part that gets the week number is
datepart(wk, DateAdd(day, 0, DateDiff(day, 0, bg_reported_date))) as [week]
It returns this output:
week bg_status status count
----------- ----------- --------------------------------------------- ------
22 1 new 1
22 5 closed 32
But it would be better to say the first date of each week, eg 01-01-2010, then 08-01-2010, etc
Question is not a duplicate of How do you get the "week start date" and "week end date" from week number in SQL Server? (answer says how to get week start from a date not from a week number)
Not a duplicate of Calculate date from week number (question asks for c#)
Not a duplicate of Get first date of week from provided date (question asks for javascript)
I did search but couldn't find this question answered for SQL Server (2010 if it matters)
If you think about it in the right way, the answer to SO 1267126 can be applied to your problem.
Each of the bug reported dates that you have in the group maps to the same week. By definition, therefore, each of those bug dates must also map to the same start of the week. So, you run the 'start of the week from given date' calculation on the bug report dates, as well as the week number calculation, and group by both (modestly ghastly) expressions, and end up with the answer you seek.
SELECT DATEPART(wk, DATEADD(day, 0, DATEDIFF(d, 0, bg_reported_date))) [week],
DATEADD(dd, -(DATEPART(dw, bg_reported_date)-1), bg_reported_date)
AS [weekstart], bg_status, st_name AS [status], COUNT(*) AS [count]
FROM bugs INNER JOIN statuses ON bg_status = st_id
GROUP BY DATEPART(wk, DATEADD(day, 0, DATEDIFF(day, 0, bg_reported_date))),
DATEADD(dd, -(DATEPART(dw, bg_reported_date)-1), bg_reported_date),
bg_status, st_name
ORDER BY [week], bg_status
Since bg_reported_date is a DATETIME (see the comment; it includes a time component), it is necessary to cast it to DATE before determining the week-start (but the week number expression doesn't need the cast, and the 'day of week' part of the week start expression doesn't need the cast either):
SELECT DATEPART(wk, DATEADD(day, 0, DATEDIFF(d, 0, bg_reported_date))) [week],
DATEADD(dd, -(DATEPART(dw, bg_reported_date)-1),
CAST(bg_reported_date AS DATE)) AS [weekstart],
bg_status, st_name AS [status], COUNT(*) AS [count]
FROM bugs INNER JOIN statuses ON bg_status = st_id
GROUP BY DATEPART(wk, DATEADD(day, 0, DATEDIFF(day, 0, bg_reported_date))),
DATEADD(dd, -(DATEPART(dw, bg_reported_date)-1),
CAST(bg_reported_date AS DATE),
bg_status, st_name
ORDER BY [week], bg_status
NB: Untested code!
I realize this is a very old thread, but "Get first date in a week, given the week number" is exactly what I wanted to do and I do NOT have an actual date to work with, so the accepted answer would not work for me. I thought I'd post my solution for posterity. Note that I suspect different culture settings MAY break this, so test before using.
My answer is built starting from this one.
Let's assume you know a week number and a year and you want to get the start and end dates for that week of that year. Here's what I have:
--These 2 "declared" variables would be passed in somehow
declare #WeekNumber int = DATEPART(wk, GETDATE())
declare #ForYear int = YEAR(GETDATE())-1
--Since we don't have a raw date to work with, I figured I could just start with
--Jan 1 of that year. I'll store that date in a cte here, but if you are doing this
--in a stored proc or function, it would make much more sense to use another #variable
;with x as
(
--this method works in SQL 2008:
SELECT CONVERT(DateTime, ('1/1/' + CONVERT(varchar, #ForYear))) as Jan1ForSelectedYear
--If you are using 2014 or higher, you can use this instead:
--DATETIME2FROMPARTS(#ForYear, 1, 1, 0,0,0,0,0)
)
--Now that we have a date to work with, we'll just add the number of weeks to that date
--That will bring us to the right week number of the given year.
--Once we have THAT date, we can get the beginning and ending of that week
--Sorry to make you scroll, but I think this is easier to see what is going on this way
SELECT CONVERT(varchar(50), DateAdd(wk, (#WeekNumber - 1), (DATEADD(dd, ##DATEFIRST - DATEPART(dw, x.Jan1ForSelectedYear) - 6, x.Jan1ForSelectedYear))), 101) as FirstDayOfWeekXForSelectedYear,
CONVERT(varchar(50), DateAdd(wk, (#WeekNumber - 1), (DATEADD(dd, ##DATEFIRST - DATEPART(dw, x.Jan1ForSelectedYear) , x.Jan1ForSelectedYear))), 101) as LastDayOfWeekXForSelectedYear
FROM x

Resources