T-SQL date between query - tsql

What is the most efficent way in T-SQL (2005) to get results from X date til today?
Attribute is RegistrationDate and is in date/time format, such as Monday, July 15, 2019 12:00 AM
I'm looking to get records where the RegistrationDate is from 20th August til Today, as this query would be running daily.
Current query is having some issues with this requirement:
cast(a.RegistrationDate as date) = cast(GETDATE() BETWEEN '2019-20-10 00:00:00.0' and GETDATE() as date)

SQL Server 2005 is long out of support, why are you still using it? If you really are still using SQL Server 2005 it's long past time you upgrade and you really need to look at upgrade paths asap. No supported versions of SQL Server support an upgrade from 2005; the newest version is 2014 which is in Extended support only.
For what you're asking, however, apart from the obvious syntax errors, the date datatype does not exist in such as old version of SQL Server. The best method is therefore use use DATEADD and DATEDIFF. I also assume that your statement " is in date/time format, such as Monday, July 15, 2019 12:00 AM" is misinformed; datetime datatypes don't have a format.
With all that I would (if I had to) do the following:
DECLARE #DateStart = '20190101',--First date in range
#DateEnd = '20200101'; --First date outside of range
SELECT ...
FROM ...
WHERE DateTimeColumn >= #DateStart
AND DateTimeColumn < #DateEnd;
If you want to make GETDATE() the start of the (current) day, then you would do:
DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)

Related

MSSQL 2014 Change returned Date in a different time zone

I have a query that returns a date as one of the column however I need that date to be in a different time zone then it currently is.
SELECT ISNULL(Value, 'NULL') AS VALUE, ISNULL(UPPER(FORMAT(start_date), 'MMM dd, yyyy hh:mm ')), 'NULL') as Start_Date FROM MY TABLE
I tried just to off set by 1 hour to make the time as in central time (currently its EST)
DATEADD(hh, -1, start_date)
the the problem comes when the date is inside daylight saving time and all returned dates within that time fate are being offest by 1 hour
Is there a way to convert that start_date column to accommodate for it?
First, I'll point out that SQL Server 2014 reached end of mainstream support on July 9th 2019. You really shouldn't be using it in a production environment any more.
If you must continue using it, then you can consider using my SQL Server Time Zone Support project. I wrote it a long time ago, and no longer maintain it, so like your server - use at your own risk.

TSQL ISO Month Week Number for ISO Year Week Number

Using TSQL I need to get the ISO Week Number in a Month for a give ISO Year Week Number.
For example: The following code will give me Week #1 for 12/31/2001, which is correct. It is the first Monday in 2002 and the first day of the ISO Year 2002.
select DATEPART(ISO_WEEK, '12-31-2001'); --Week 1 January 2002
My question is how do I...
(1) Take the ISO Week Number Example: ISO Year Week Number: 14 for April 4, 2016 (April Week #1).
(2) Now Take ISO Year Week Number 14 and return April Month Week Number = 1 for the example above.
There seems to be nothing in SQL Server to get the ISO Month Week# from the ISO Year Week Number. I have a function I wrote but it is has some hacks to get it to work, but not 100%.
I think you want something like this... but am not sure why you need the ISO_WEEK. Just replace getdate() with your column.
select datepart(wk, getdate()) - datepart(wk,dateadd(m, DATEDIFF(M, 0, getdate()), 0)) + 1
After attempting to handle getting ISO Month Week Number in functions I decided an easier solution was to create an ISO_Calendar table in SQL Sever.
We know in TSQL you can get the ISO Year Week Number and some a bit of work the ISO Year Number. The ISO Month Week Number is another story.
I build the table shown below with data from 2000 to 2040 by populating all the columns other than the ISO Month number. Then on a second pass I looped through the table and set the ISO Month number based on the Month# in the Monday Date.
Now if I want to get the ISO Month number for a date I check #Date between Monday and Sunday. In my case I am only concerned with dates between Monday and Friday since this is for a stock analysis site.
select #ISOMonthWeekNo = c.ISOMonthWeekNo
from ISO_Calendar c
where #TransDate between c.Monday and c.Sunday;
The advantage is the table is a one time build and easier to verify the accuracy of the data.

Between Date Time T-SQL

I have the following Where clause which is causing me issues and I am looking for a work around.
#startDate is the todays date and #endDate is the end date which could be 7 days, 14 days or 20 days in the future, this works fine unless the end month is greater than the start month.
ISSUE- if the StartDate DAY is 20 and the END Date Day is in the next Month example Start Day is 10/21 and End Day is 11/5 than the where clause cancels its self out, I can't use a Between because we are not including the yr.
I tried an OR but this also doesn't work.
WHERE DAY(t.AnniversaryDate) >= DAY(#startDate)
AND DAY(t.AnniversaryDate) <= DAY(#endDate)
AND MONTH(t.AnniversaryDate) >= MONTH(#startDate)
AND MONTH(t.AnniversaryDate) <= MONTH(#endDate)
AND YEAR(t.AnniversaryDate) < YEAR(GETDATE())
The expression
select DATEADD(year,DATEDIFF(year,'19780517',GETDATE()),'19780517')
Will always return the 17th of May of the current year. A similar expression can be used to perform the same trick for any date1 by replacing both instances of '19780517' with the date of interest.
So, whatever "I can't use a Between because we are not including the yr" means, you should be able to work around it by using the above expression.
So, I think what you want would be:
WHERE DATEADD(year,
DATEDIFF(year,t.AnniversaryDate,GETDATE()),
t.AnniversaryDate)
BETWEEN #startDate and #endDate
1So long as you're happy that 29th February maps to 28th February if you ask for it in a non-leap year.

Need to sort by Date then Hour, then output Date, text Day of week , range of hours SQL Server 2008 R2

NEWBIE at work! I am trying to create a simple summary that counts the number of customer visits and groups by 1) date and 2) hour, BUT outputs this:
Date Day of Wk Hour #visits
8/12/2013 Monday 0 5
8/12/2013 Monday 1 7
8/12/2013 Monday 6 10
8/13/2013 Tuesday 14 25
8/13/2013 Tuesday 16 4
We are on military time, so 14 = 2:00 pm
Select
TPM300_PAT_VISIT.adm_ts as [Date]
,TPM300_PAT_VISIT.adm_ts as [Day of Week]
,TPM300_PAT_VISIT.adm_ts as [Hour]
,count(TPM300_PAT_VISIT.vst_ext_id) as [Total Visits]
From
TPM300_PAT_VISIT
Where
TPM300_PAT_VISIT.adm_srv_cd='22126'
and TPM300_PAT_VISIT.adm_ts between '07-01-2013' and '08-01-2013'
Group by
cast(TPM300_PAT_VISIT.adm_ts as DATE)
,datepart(weekday,TPM300_PAT_VISIT.adm_ts)
,datepart(hour,TPM300_PAT_VISIT.adm_ts)
Order by
CAST(TPM300_PAT_VISIT.adm_ts as DATE)
,DATEPART(hour,TPM300_PAT_VISIT.adm_ts)
This should solve the problem:
; With Streamlined as (
SELECT
DATEADD(hour,DATEDIFF(hour,'20010101',adm_ts),'20010101') as RoundedTime,
vst_ext_id
from
TPM300_PAT_VISIT
where
adm_srv_cd='22126' and
adm_ts >= '20130701' and
adm_ts < '20130801'
)
Select
CONVERT(date,RoundedTime) as [Date],
DATEPART(weekday,RoundedTime) as [Day of Week],
DATEPART(hour,RoundedTime) as [Hour],
count(vst_ext_id) as [Total Visits]
From
Streamlined
Group by
RoundedTime
Order by
CONVERT(date,RoundedTime),
DATEPART(hour,RoundedTime)
In the CTE (Streamlined)'s select list, we floor each adm_ts value down to the nearest hour using DATEADD/DATEDIFF. This makes the subsequent grouping easier to specify.
We also specify a semi-open interval for the datetime comparisons, which makes sure we include everything in July (including stuff that happened at 23:59:59.997) whilst excluding events that happened at midnight on 1st August. This is frequently the correct type of comparison to use when working with continuous data (floats, datetimes, etc), but means you have to abandon BETWEEN.
I'm also specifying the dates as YYYYMMDD which is a safe, unambiguous format. Your original query could have been interpreted as either January 7th - January 8th or 1st July - 1st August, depending on the settings of whatever account you use to connect to SQL Server. Better yet, if these dates are being supplied by some other (non-SQL) code, would be for them to be passed as datetimes in the first place, to avoid any formatting issues.

SQL DateDiff Weeks - Need and alternative

The MS SQL DateDiff function counts the number of boundaries crossed when calculating the difference between two dates.
Unfortunately for me, that's not what I'm after. For instance, 1 June 2012 -> 30 June 2012 crosses 4 boundaries, but covers 5 weeks.
Is there an alternative query that I can run which will give me the number of weeks that a month intersects?
UPDATE
To try and clarify exactly what I'm after:
For any given month I need the number of weeks that intersect with that month.
Also, for the suggestion of just taking the datediff and adding one, that won't work. For instance February 2010 only intersects with 4 weeks. And the DateDiff calls returns 4, meaning that simply adding 1 would leave me the wrong number of weeks.
Beware: Proper Week calculation is generally trickier than you think!
If you use Datepart(week, aDate) you make a lot of assumptions about the concept 'week'.
Does the week start on Sunday or Monday? How do you deal with the transition between week 1 and week 5x. The actual number of weeks in a year is different depending on which week calculation rule you use (first4dayweek, weekOfJan1 etc.)
if you simply want to deal with differences you could use
DATEDIFF('s', firstDateTime, secondDateTime) > (7 * 86400 * numberOfWeeks)
if the first dateTime is at 2011-01-01 15:43:22 then the difference is 5 weeks after 2011-02-05 15:43:22
EDIT: Actually, according to this post: Wrong week number using DATEPART in SQL Server
You can now use Datepart(isoww, aDate) to get ISO 8601 week number. I knew that week was broken but not that there was now a fix. Cool!
THIS WORKS if you are using monday as the first day of the week
set language = british
select datepart(ww, #endofMonthDate) -
datepart(ww, #startofMonthDate) + 1
Datepart is language sensistive. By setting language to british you make monday the first day of the week.
This returns the correct values for feburary 2010 and june 2012! (because of monday as opposed to sunday is the first day of the week).
It also seems to return correct number of weeks for january and december (regardless of year). The isoww parameter uses monday as the first day of the week, but it causes january to sometimes start in week 52/53 and december to sometimes end in week 1 (which would make your select statement more complex)
SET DATEFIRST is important when counting weeks. To check what you have you can use select ##datefirst. ##datefirst=7 means that first day of week is sunday.
set datefirst 7
declare #FromDate datetime = '20100201'
declare #ToDate datetime = '20100228'
select datepart(week, #ToDate) - datepart(week, #FromDate) + 1
Result is 5 because Sunday 28/2 - 2010 is the first day of the fifth week.
If you want to base your week calculations on first day of week is Monday you need to do this instead.
set datefirst 1
declare #FromDate datetime = '20100201'
declare #ToDate datetime = '20100228'
select datepart(week, #ToDate) - datepart(week, #FromDate) + 1
Result is 4.