Get the difference in weeks, data stored as YYYYWW in TSQL - sql-server

I have customer_since stored as YYYYWW i.e., 201852.
The below script is what I have been using to work out the difference, however when I have this situation of 201901 - 201852, it gives 48 instead of 1.
is there mod function or something that can be incorporated here to resolve the issue?
CAST(CONCAT (DATEPART(YEAR, DATEADD(MONTH, + 9, GETDATE()))
, RIGHT('0' + RTRIM(DATEPART(WEEK, DATEADD(MONTH, - 3, GETDATE()))+1),2)
) AS INT) - a.customer_since AS Customer_since

You can use the following template to get the first (or the last) date of a given year and week. Then having valid date times, simply use DATEDIFF as it has built in functionality to get difference in weeks:
DECLARE #WeekNo int= 52
DECLARE #Year int=2018
SELECT DATEADD(wk,#WeekNo-1,DATEADD(yy,#Year-1900,0)) AS WeekStart,
DATEADD(wk,#WeekNo,DATEADD(yy,#Year-1900,0))-1 AS WeekEnd
GO
DECLARE #WeekNo int= 1
DECLARE #Year int=2019
SELECT DATEADD(wk,#WeekNo-1,DATEADD(yy,#Year-1900,0)) AS WeekStart,
DATEADD(wk,#WeekNo,DATEADD(yy,#Year-1900,0))-1 AS WeekEnd
GO
SELECT DATEDIFF(WEEK, '2018-12-24 00:00:00.000', '2019-01-01 00:00:00.000')
In one statement:
DECLARE #Input01 VARCHAR(6) = '201852'
,#Input02 VARCHAR(6) = '201901'
SELECT DATEDIFF(WEEK, DATEADD(WEEK, RIGHT(#Input01, 2)-1,DATEADD(YEAR,LEFT(#Input01, 4)-1900,0)), DATEADD(WEEK,RIGHT(#Input02, 2)-1,DATEADD(YEAR,LEFT(#Input02, 4)-1900,0)));

You can create a function which will accept the date string('201852') and will return a date like `Create Function Todate(#dt varchar(100))
returns Date
Begin
Declare #wk int=(Select RIGHT(#dt,2))
return (Select Dateadd(WK, #wk, cast(LEFT(#dt,4) as date)))
End`
Now all you have to do is pass the date string in the function and find a DATEDIFF with start and End date

Related

Let the user select how many days of data he wants

declare #Days varchar(max)
set #Days = '-7'
select
dateadd(hour,datepart(hour,Timestamp + GETDATE() - GETUTCDATE()),cast(CAST((Timestamp + GETDATE() - GETUTCDATE()) as date) as datetime)) as [Time]
from [Employee]
where dateadd(hour,datepart(hour,Timestamp + GETDATE() - GETUTCDATE()),cast(CAST((Timestamp + GETDATE() - GETUTCDATE()) as date) as datetime)) >= DATEADD(day,' + #Days + ', GETDATE()))
I want the user to select the number of days(#Days) of data he wants. So if he wants the data for last 15 days, all he has to do is set #Days = '-15'. Timestamp is the date along with time Column in my Employee table but Timestamp is UTC. I have written the query above and it is returning some data but I am confused if the query is correct or not?
I think the following simple query should do the trick.
declare #Days INT = -7; --<-- Use int not varchar
SELECT *
FROM [Employee]
WHERE CAST([Timestamp] AS DATE) >= CAST(DATEADD(day, #Days, GETUTCDATE()) AS DATE);
DATEADD() function's 2nd parameter is an int, you can pass the variable #Days to the function as it is.

EXACT MONTH Difference in SQL SERVER

I want to find the exact month difference. for e.g. 6 Months difference from today,
Consider Today and 6 Months before is 2018-01-14. If you see the dates 6 Months is over and it is 6 Months ,1 day.I want to display it as 7 months . i tried the below query but it returns complete months.
select DATEDIFF(MONTH,'2018-01-15 10:49:36.237',GETDATE())
Two ways:
One using select:
select
datediff(month,'2012-April-09','2013-April-08') MonthsInService
,datediff(day,'2012-April-09','2013-April-08')/365 YearsInService
Second using a function:
CREATE FUNCTION [dbo].[getFullYears]
(
#dateX datetime,
#dateY datetime
)
RETURNS int
AS
BEGIN
DECLARE #y int
SET #y =DATEDIFF(year,#dateX,#dateY)
IF (#dateY < DATEADD(year, #y, #dateX)) SET #y = #y -1
RETURN #y
END
select dbo.getFullYears('2012-April-09','2013-April-09') --1
select dbo.getFullYears('2012-April-09','2013-April-08') --0
refer this post as well for month calculation, it will complete my answer overall.
You can find year, month and day by this
WITH ex_table AS (
SELECT '2018-01-15 10:49:36.237' 'monthbefore',
getdate() 'visitdatetime')
SELECT CAST(DATEDIFF(yy, t.monthbefore, t.visitdatetime) AS varchar(4)) +' year '+
CAST(DATEDIFF(mm, DATEADD(yy, DATEDIFF(yy, t.monthbefore, t.visitdatetime), t.monthbefore), t.visitdatetime) AS varchar(2)) +' month '+
CAST(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, DATEADD(yy, DATEDIFF(yy, t.monthbefore, t.visitdatetime), t.monthbefore), t.visitdatetime), DATEADD(yy, DATEDIFF(yy, t.monthbefore, t.visitdatetime), t.monthbefore)), t.visitdatetime) AS varchar(2)) +' day' AS result
FROM ex_table t
You can use this :
declare #date as varchar(50)
set #date = '2018-01-15 10:49:36.237'
select DATEDIFF(MONTH, #date, GETDATE()) as [Month], DATEDIFF(day, #date, GETDATE())%30 as [Day]
Output
Month Day
6 2

How to declare dates in SQL multiple value

I am trying to create my SQL syntax so that we can have versatile input. I figured out how to do it for one set date and it worked.
my syn is:
DECLARE #MyDay AS VARCHAR(50);
DECLARE #NextDay AS VARCHAR(50);
SET #MyDay = '8/30/2016';
SET #NextDay = DATEADD(d, 1, #MyDay);
However, I'm stuck with how to do it for multiple dates. Ideally I would like to put in a range of date, and from that it will scan the records, i.e. set range between oct 1st and oct 5th.
I'm using SQL Server Management Studio 2008
If you just want a series of days and next days between 8/30/16 and 9/5/16, you can use a derive table method like below.
declare #n int;
declare #StartDate datetime, #EndDate datetime;
set #n = 5;
set #StartDate = '20160830';
set #EndDate = dateadd(day, #n, #StartDate);
select cast(dateadd(day, number, #StartDate) as date) as MyDate,
cast(dateadd(day, number + 1, #StartDate) as date) as MyNextDate
from
(select distinct number from master.dbo.spt_values
where name is null
) n
where dateadd(day, number, #StartDate) < #EndDate;
Alternately you can use a temp table, table variable to store your dates, or a cte as well.
A recursive cte imlementation example is given below. Please note you would want to set MAXRECURSION option if you have a long date range as default for max recursion is 100.
declare #n int;
declare #StartDate datetime, #EndDate datetime;
set #n = 5;
set #StartDate = '20160830';
set #EndDate = dateadd(day, #n, #StartDate);
;with DateSeq as
(
select cast(#StartDate as date) as MyDate
union all
select dateadd(day , 1, MyDate) AS MyDate
from DateSeq where dateadd (day, 1, MyDate) < #EndDate
)
select MyDate, dateadd(day , 1, MyDate) AS NextDate
from DateSeq;
A temp table implementation example is as below.
declare #MyDateRange table(MyDate date);
Insert into #MyDateRange values('8/30/2016')
Insert into #MyDateRange values('9/1/2016')
Insert into #MyDateRange values('9/2/2016')
Insert into #MyDateRange values('9/3/2016')
Insert into #MyDateRange values('9/4/2016')
select MyDate, dateadd(day, 1, MyDate) as NextDate from #MyDateRange

Calculating DATEDIFF(Month) in SQL Server

I am using the DateDiff function to find the number of months between two dates. But I am facing the problem like if the difference is 1 month and 3 days it is not giving as 2 months.
SELECT *
FROM tablename
WHERE
DATEDIFF(month, CONVERT(DATE, CONVERT(DATE, '20/10/2013', 103), 120),
CONVERT(DATE, CONVERT(DATE, '25/11/2013', 103), 120)) > 2
Result should be 2 but it is giving 1
The date column in the table is varchar type values are stored as dd/mm/yyyy. Even one day in the month should be calculated as 1 month
Got the Answer
ALTER FUNCTION [dbo].[CalculateNumberOfMonths]
(
#date1 varchar(50),
#date2 varchar(50)
)
RETURNS varchar(10)
AS
BEGIN
declare #days int
declare #months int
select #days = datediff(day,CONVERT(DATE,#date1,103),CONVERT(DATE,#date2,103))
select #months = datediff(month,CONVERT(DATE,#date1,103),CONVERT(DATE,#date2,103))
if(#days % 7 >0)
begin
set #months= #months + 1
end
RETURN #months
END

TSQL Filtering a query by time / hours

Ok, I'm running query builder out of visual studio 2008. I'm trying to filter the results of the query by time; that is, I want to pull everything from the start of yesterday to noon yesterday.
I've been using GETDATE()-1 for yesterday, which pulls up a timestamp mm/dd/yyyy hh:mm:ss
however, it pulls the current time. to get it to run from the start of the day I appended the timestamp to remove the time itself, so it started at the beginning of the day:
convert(varchar(10), getdate()-1, 120)
so I'm using between to find the range, I have:
BETWEEN convert(varchar(10), getdate()-1, 120) AND // this is where I need it to cut off at noon.
I'm understanding that datetime is a data type here, so I tried subtracting the hours/minutes/seconds using date part, but datepart() only returns ints and doesn't affect the time.
thoughts? how do I get this to cut off at noon
Try this:
--Variables
declare #now datetime = getdate(),
#yesterday datetime
--Yesterday starting datetime
select #yesterday = convert(datetime, convert(date, dateadd(day,-1,#now)))
--Your query to filter between y'day start and y'day noon
--Note that between means inclusive boundary values. (or use >= and <=)
select * from yourTable
where dateCol between #yesteray and dateadd(hour,12,#yesterday)
DECLARE
#Min DATETIME
, #Max DATETIME
SELECT
#Min = DATEADD(DAY, -1, CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME))
, #Max = DATEADD(HOUR, 12, CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME))
SELECT *
FROM <Table> x
WHERE x.[Date] BETWEEN #Min AND #Max
SELECT * FROM T WHERE YourDate BETWEEN CAST(GETDATE()-1 As DATE) AND DATEADD(Hour, -12, CAST(CAST(GETDATE() As DATE) As DATETIME) )
Beware because BETWEEN will include lower and upper boundaries, so you can simply replace BETWEEN with x >= y and y < z if you don't want yesterday at 12:00 to be taken in account
between DateAdd(day, -1, cast(getdate() as date)) and DateAdd(hour, -12, cast(getdate() as date))
Edit: As mentioned in the comments, you can't use hours with a date, you have to cast it back to a datetime, thus:
between DateAdd(day, -1, cast(getdate() as date)) and DateAdd(hour, -12, cast(cast(getdate() as date) as datetime))
If you want to get the results from last 30 mins you need to use this. You can change MINUTE to HOUR too.
--Get now, hour and second included
DECLARE #NOW DATETIME = GETDATE()
--Get 30 mins from now
DECLARE #TranDate DATETIME
SET #TranDate = CONVERT(DATETIME, CONVERT(DATETIME, DATEADD(MINUTE,-30,#NOW)))
After That, add below code to your where statement,
AND TK.TransactionDate >= #TranDate

Resources