DateDiff SQL Server Problem - sql-server-2005

Could some one please explain this to me as I am a touch confused as to why this is happening? Basically what I would like to know is why there is a difference between Sundays date and every other day of this week in weeks from the year 0. If that makes sense!
I tried setting the date first but this had no effect. Surely Monday – Sunday of this week should all have the same difference in weeks from the year zero?
Set Datefirst 1
Select DateName(dw,0) --Monday
Select DateDiff(week, 0, '20091109')--Monday: Difference 5732
Select DateDiff(week, 0, '20091114')--Saturday: Difference 5732
Select DateDiff(week, 0, '20091115')--Sunday: Difference 5733
What makes this even more bizarre is if you take the same two dates and date diff them you get one week for the one and 6 days for the other. Am I missing something here?
Select DateDiff(dd,'20091109','20091115')--6 Days difference
Select DateDiff(ww,'20091109','20091115')--1 Week difference
I am using SQL Server 2005

Sunday is considered the first day of the week in a number of countries.

All the datediff functions do is count the number of date boundarys between the two datetime arguments passed to it. So if a week is defined to start Sunday, then the week boundary is midnight Sunday Morning.
So, From 11:59 Saturday night to 00:01 am Sunday Morning, will be the same datediff(week, x, y) as from 00:01 Sunday to 11:59 PM Saturday Night - 13 days later.
x ------------------------------x ==> 1 week diff
| Su M T W T F S | Su M T W T F S |
| | |
x-x ==> Also 1 week diff

I think the problem you are facing is the boundary dates. Are they inclusive?
Select DateDiff(dd,'20091109','20091115')--6 Days difference
Select DateDiff(dd,'20091109','20091116')--7 Days difference
DateDiff - Returns the number of date and time boundaries crossed between two specified dates. (Books Online Definition)

If you Set Datefirst = 1, Monday is the first day of the week, and the week calculations would use MOD 7 for number of days in the week and /7 for week count, in which sunday would be used as 1, and the others FLOORed to 0.

Related

How to query last Saturday and the one before in SQL?

I would like to query data, which is between some week days, as follows:
Last Saturday
The Sunday before it
The Saturday before that queried Sunday on 2.
The Sunday before that queried Saturday on 3.
The query would run automatically every Monday, so I would like to set a dynamic condition for it, so that it automatically picks that days, without depending on any day it will run on in the future.
So for example if today is Monday 01/08/2018:
would be 01/06/2018
would be 12/31/2017
would be 12/30/2017
would be 12/24/2017
I would like to set that conditions in the WHERE clause. For now I am querying it this way, with constant dates for example for last week data:
SELECT *
FROM thisTable
WHERE Date(operation_date) BETWEEN '2018-06-10' AND '2018-06-16'
DBMS: Amazon Redshift
The DATE_TRUNC Function is your friend. It truncates to a Monday.
SELECT
CURRENT_DATE AS today,
DATE_TRUNC('week', CURRENT_DATE) as most_recent_monday,
DATE_TRUNC('week', CURRENT_DATE) - 2 AS most_recent_saturday,
DATE_TRUNC('week', CURRENT_DATE) - 8 AS sunday_before_most_recent_saturday
Returns:
2018-06-21 | 2018-06-18 00:00:00 | 2018-06-16 00:00:00 | 2018-06-10 00:00:00
Note that it treats the date as midnight at the beginning of the day. So, you don't really want to query Sunday to Saturday. You actually want to query Sunday to Sunday (which really means midnight at the start of Sunday to midnight at the start of the next Sunday). This assumes your source date is a timestamp.
If your source date is purely a date, then you would want to use Sunday to Saturday.
If you want to query everything from "last week" (if your definition is Sunday to Sunday), and assuming a timestamp, use:
SELECT *
FROM thisTable
WHERE operation_date BETWEEN
-- Most recent Monday minus 8 days = Two Sundays ago
DATE_TRUNC('week', CURRENT_DATE) - 8 AND
-- Most recent Monday minus 1 day = Most recent Sunday
DATE_TRUNC('week', CURRENT_DATE) - 1
(Well, unless you're on a Sunday already, but that's your problem!)
If the date is a date, you'd have to adjust it a bit.
last Sat: date_trunc('week',getdate())-interval '2 day'
prev Sat: date_trunc('week',getdate())-interval '9 day'
this is for Monday-based week

How to subtract 13 weeks from a date in PL SQL?

I have a date in sql which will always fall on a Monday and I'm subtracting 13 weeks to get a weekly report. I am trying to get the same 13 week report but for last year's figures as well.
At the moment, I'm using the following:
calendar_date >= TRUNC(sysdate) - 91
which is working fine.
I need the same for last year.
However, when I split this into calendar weeks, there will also be a partially complete week as it will include 1 or 2 days from the previous week. I need only whole weeks.
e.g. the dates that will be returned for last year will be 14-Feb-2015 to 16-May-2015. I need it to start on the Monday and be 16-Feb-2015. This will change each week as I am only interested in complete weeks...
I would do this:
Get the date by substracting 91 days as you're already doing.
Get the number of the day of the week with TO_CHAR(DATE,'d')
Add the number of days until the next monday to the date.
Something like this:
SELECT TO_DATE(TO_DATE('16/05/2015','DD/MM/YYYY'),'DD/MM/YYYY')-91 + MOD(7 - TO_NUMBER(TO_CHAR(TO_DATE(TO_DATE('16/05/2015','DD/MM/YYYY'),'DD/MM/RRRR')-91,'d'))+1,7) d
FROM dual
next_day - returns date of first weekday named by char.
with dates as (select to_date('16/05/2015','DD/MM/YYYY') d from dual)
select
trunc(next_day( trunc(d-91) - interval '1' second,'MONDAY'))
from dates;
I want to get next monday from calculated date. In situation when calculated date is monday i have to move back to previous week ( -1 second).

SQL Server: Count number of records on weekly basis (Week = Thursday to Wednesday)

I need some help in writing an SQL in SQL Server where I need to count number of rows group by weeks. There is a tricky description of week which is following
- For any date before 08/13/2015 the week is of 7 days (i.e. from Thu through Wed)
- For date 08/13/2015 the week is consider a 9 day week (i.e. from Thursday through Friday so its between 08/13/2015 through 08/21/2015)
- For date 08/22/2015 the week is back to 7 days (i.e. Sat through Friday)
Now having said all the above the result I want to see in my report is the following way . NOTE: WE column in the below attached image is the last day of the week for the range.
Sample Result Image
Just write a case statement for the 3 different options. You can find the start day with something like this:
DATEADD(week, DATEDIFF(day, 3,getdate()) / 7, 3) -- Thursdays
DATEADD(week, DATEDIFF(day, 5,getdate()) / 7, 5) -- Saturdays
The numbers 3 and 5 come from the fact that day 0 (=1.1.1900) is Monday.
If you use this a lot, it might be a good idea to write a inline table valued function to return the dates you need.

Pulling a dynamic day range from the previous year in DB2

I have two current SQL queries that I currently use to compare GM% from previous year vs. GM% this year. This is a daily report that I run every morning. The date arithmetic is not very solid and I am trying to find an alternative. Previously I thought that the report would only be for Monday forward, and not including the current day (ie if ran on Tuesday, it would only pull Monday. If ran on Monday it would not pull anything.) Recently that has changed to where when the report is ran on Monday, they want to see Friday-Sunday. What I am considering is setting it to pull the previous 5 day, not including the current day. (Ran on Monday would pull Thur, Fri, Sat, Sun.) The problem is that it has to be a day this year vs same day last year comparison. Anyone who;s tried this knows that it is not easy to get this. Here is my current code for the date arithmetic. I am at a loss guys, I could use some help.
Where DB1.TB1.CLM1>=Current Date-364 days - (DAYOFWEEK(CURRENT DATE) - 2) DAYS
And DB1.TB1.CLM1< Current Date- 364 days
If I hear you right, on Tuesday you would pull stats for Monday. Wed, you pull stats for Mon-Tues. Friday, you pull Mon-Thurs. And for all of these, you need the equivalent day prior year.
The trick is that now on Monday, you need to pull the previous weekend, i.e. Thu-Sun.
You have not defined what to do on Sunday, so I'm leaving that case out.
Try this WHERE statement:
where
( -- do this after Monday
dayofweek(current date) > 2 and
DB1.TB1.CLM1 between ((current date - 364 days) - (dayofweek(current date) - 2) days) and (current_date - 365 days)
)
or
( -- do this on Monday
dayofweek(current date) = 2 and
DB1.TB1.CLM1 between (current date - 368 days) and (current date - 365 days)
)

Get 1st Day of Week (Sunday)

I have this formula in my column to calculate the start date of a given week :
dateadd(week,[Week]-(1),
dateadd(day,(-1),
dateadd(week,
datediff(week,(0),
CONVERT([varchar](4),[Year],(0))+'-01-01'),
(1))))
Where Week and Year are other fields like 38 and 2012
Problem is, it calculates the start date of week 38/2012 as a monday (17th Sept), I would like it to be a sunday instead (16th Sept) is this possible?
Many thanks.
This will return you the first day of the week, given a week number and a year, assuming that the first day of the week is a Sunday.
Standard exclusions apply, e.g. don't try year 1499.
declare #tbl table ([Week] int, [Year] int)
insert #tbl select 38,2012
union all select 1,2012
union all select 0,2012
union all select 1,2013
select DATEADD(
Week,
[Week]-1,
DATEADD(
Day,
(8-##datefirst)-DATEPART(dw, CAST([Year]*10000+101 AS VARCHAR(8))),
CAST([Year]*10000+101 AS VARCHAR(8))))
from #TBL
Result
2012-09-16 00:00:00.000
2012-01-01 00:00:00.000
2011-12-25 00:00:00.000
2012-12-30 00:00:00.000
Note that the Week number starts from 1, and if the week doesn't start on a Sunday, then the first day of that week could end up in an earlier year (row #4). Because the Weeks are relative, you can use Week 0, -1 etc and it will still give you a result (row #3), rightly or wrongly.
You may also notice I used a different method to create a date out of the year, just as an alternative.
The (8-##datefirst) portion of the query makes it robust regardless of your DATEFIRST setting.
If you want the first day of the week to be Sunday you could change your database to make it so, using the DATEFIRST setting.
function getFirstDateOfThisWeek(d)
{
var TempDate = new Date(d || new Date());
TempDate.setDate(TempDate.getDate() + (#Config.WeekStartOn - 1 - TempDate.getDay() - 7) % 7);
return TempDate;
}
var StartDate = getFirstDateOfThisWeek(new Date()); //1st date of this week