Converting year month day to date in sql server - sql

My input to the stored procedure is a string (e.g '2 years 3 months 4 days') which is a future date. How to convert this to a date by comparing with current date?

declare #S varchar(50)
set #S = '2 years 3 months 4 days'
select dateadd(day, D.D, dateadd(month, D.M, dateadd(year, D.Y, getdate()))) as TheDate
from (select replace(replace(replace(#S, ' years ', '.'), ' months ', '.'), ' days', '')) as T(S)
cross apply (
select cast(parsename(T.S, 1) as int),
cast(parsename(T.S, 2) as int),
cast(parsename(T.S, 3) as int)Y
) as D(D, M, Y)
SQL Fiddle

You can use below Query in SP
select dateadd(yy,2,dateadd(m,3,dateadd(d,4,GETDATE())))
^Year ^Month ^Days
Here is the SP
create procedure test1
(
#year INT,
#month INT,
#day INT
)
AS
BEGIN
select dateadd(yy,#year,dateadd(m,#month,dateadd(d,#day,GETDATE())))
END

Use DATEADD, for example (add one year, to the current data):
DECLARE #datetime2 datetime2 = getdate();
SELECT 'year', DATEADD(year,1,#datetime2)
...
So, you should add 2 years, 3 months and 4 days to the current date and then return it as normal date (here I returned future year). Read here for details.
Before of the stored procedure invocation you should split the string in a server side language like PHP:
$str = '2 years 3 months 4 days';
preg_match_all('!\d+!', $str, $data);
So $data[0]=2, $data[1]=3 and $data[2] = 4, and so you can invoke #Luv procedure:
create procedure test1 -- thanks to Luv
(
#year INT,
#month INT,
#day INT
)
AS
BEGIN
select dateadd(yy,#year,dateadd(m,#month,dateadd(d,#day,GETDATE())))
END

https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
Convert seconds to human readable time duration
you may be able to split & convert this formatting into something which is useable via builtin SQL-functions - but i'd recommend using at least a pre-processing scriptlanguage like PHP in order to format the time correctly, PHP "relative" formats may just be the thing, i recall the datetime-class being quite powerful ...
http://www.php.net/manual/en/datetime.construct.php
http://www.php.net/manual/en/datetime.formats.relative.php
http://www.php.net/manual/en/datetime.formats.compound.php

Related

Compare the date if the columns (day, month and year) are stored separately in SQL Server

I have 3 columns Day, Month and Year of type INT that are totally separate. What I need is to pass a date (format: yyyy-mm-dd) into a WHERE clause to check if this following date is matched or not. What would be the best approach to handle this issue?
In 2012 it would be DateFromParts(Year,Month,Day), but you have tagged 2008 which means we have to fall back to the older tricks.
dateadd(mm, (#YourYearValue - 1900) * 12 + #YourMonthValue- 1 , #YourDayValue - 1)
Put your 3 ints into that (via columns from a join or parameters as appropriate) and you have a date returned you can work with.
SQL Fiddle : http://www.sqlfiddle.com/#!18/9eecb/19988
For SQL Server 2008
declare #Day int = 29, #Month int = 5, #Year int = 2018
select t.*
from [table] t
where t.[Date] = cast(cast(#Year as char(4))+ '-' + cast(#Month as char(2)) + '-' + cast(#Day as char(2)) as date)
Only for 2012 and later use DATEFROMPARTS:
where t.[Date] = DATEFROMPARTS(#Year, #Month, #Day)
Maybe this solution:
where cast(cast(#yyyy as varchar(4))+'-'+cast(#mm as varchar(2))+'-'+cast(#dd as
varchar(2)) as date) ...
and replace #yyyy,#mm,#dd with your fields
I would suggest the following, Instead of making a date using separated values we can take part from the complete date using SQL functions and compare with accordingly, which I think the best way of comparison
DECLARE #Day INT=29, #Month INT=05, #Year INT = 2018,
#Date DATE = '2018-05-29'
SELECT * FROM yourTable
WHERE YEAR(#Date) = #Year
AND MONTH(#Date) = #Month
AND DAY(#Date) = #Day

Check a date (excluding year)

In SQL Server, how can I check if one calendar date consisting of a day and month is older than another certain date, programmatically?
For example: I need to check if TransactionDate is on or before June 30, in all year.
TransactionDate <= (June 30)
Use DATEPART like this:
declare #var1 date = '2016-02-07';
declare #var2 date = '2017-02-06';
SELECT CASE
WHEN DATEPART(MM, #var1 ) * 100 + DATEPART(DD, #var1 )
> DATEPART(MM, #var2 ) * 100 + DATEPART(DD, #var2 ) THEN 'YES'
ELSE 'NO' END AS LARGERDATE;
It compares the dates as two integers in form of MMDD. For example:
'2016-02-07' ==> 207, '2017-02-06' ==> 206
'2010-10-27' ==> 1027, '2017-07-29' ==> 729
Most correct way will be to use DATEPART function; especially because it is available from all versions of SQL server since 2008, Azure SQL Database, Azure SQL Data Warehouse and Parallel Data Warehouse too.
You can check using the expression assuming you have the date to be compared against stored in #yourCheckDate variable
DECLARE #yourCheckDate DATETIME
DECLARE #m INT
DECLARE #d INT
SELECT #yourCheckDate = CAST('2017-6-30 12:15:32' AS DATETIME)
SELECT #m= DATEPART(month, #yourCheckDate)
SELECT #d= DATEPART(day, #yourCheckDate)
-- expression
select 1 where
DATEPART(month,#tranDate) < #m
OR
( DATEPART(month,#tranDate) = #m AND DATEPART(day,#tranDate) <= #d )
A SQL Server 2008 solution which supports any calendar date, derived from #TheEsisia and #Sami answers
WHERE 100*MONTH(TransactionDate) + DAY(TransactionDate) <= 100*MONTH(#checkDate) + DAY(#checkDate)
This should work if you want to get all dates from a date to the end of the year. Basically constructing a 'xxxx-12-31' with the input date (example in Oracle).
BETWEEN yourDate AND TO_DATE(TO_CHAR(yourDate, 'YYYY') ||'12-31', 'YYYY-MM-DD')

Working out a date from a single month number SQL

Got 2 parameters #yr and #period, #period is just the month number so July would equal 7 for example.
In my stored procedure table I've got a column called Date which is just a standard datetime field. I need a where clause to work out all dates greater than the current period minus 1 year so if #period = 7 and #yr = 2012 I want the where clause to return all dates greater than '01-07-2011' (UK date format) how can I achieve this with just the 2 numbers from #period and #yr.
WHERE <br>
Date >= '01-07-2011'
You could
Date >= dateadd(month, #period-1, dateadd(year, #yr-1900, 0))
where year(date)>year(getdate()-1) and month(date)>#period
If you want the expression sargable, convert it to datetime:
declare #year int = 2012
declare #month int = 7
select
...
where [Date] >= convert(datetime, convert(varchar(4), #year)
+ right('0' + convert (varchar(2), #month), 2)
+ '01')
After seeing Alex K.'s answer, you might even do this:
dateadd(month, #month - 1 + (#year-1900) * 12, 0)
For the best performance you should do something like this:
declare #yr int = 2012
declare #period int = 7
select ...
from ....
WHERE date >= dateadd(month, (#yr - 1901) * 12 + #period - 1, 0)
We can do it in may ways
try it
DECLARE #a VARCHAR(20),
#b VARCHAR(10),
#c varchar(4)
SET #b='may' /*pass your stored proc value */
SET #c='2011'
SET #a='01'+#b+#c
SET DATEFORMAT YDM
SELECT CAST(#a AS DATE)
FOR uk formate
SELECT CONVERT(char,CAST(#a AS DATE),103)
Just t make sure you compare against an entire date, one solution I'd offer is:
Select *
from TheTable
where date> DateAdd(Year,-1, convert(datetime, '01/'+convert(varchar,#period)+'/' + convert(varchar,#yr)))
To account for regional format differences in SQL Server 2012:
Select *
from TheTable
where date> DateAdd(Year,-1, DateFromParts(#year,#period,1))
For pre-2012:
Select *
from TheTable
Where Date > DateAdd(day, 0, DateAdd(month, #period-1, DateAdd(year, (#yr-1900)-1,0)))
The #yr-1900 is maintained to illustrate the computation of the base date offset from 1900, then subtracting 1 for the one-year-off date computation

How to get date difference between two dates in same year with one date is from an input date not from the year

Well this is my case: I have an input date X (dd-mm-yyyy), and I want to count the number of days between it with the year part is changed into current year and today's date in SQL. I t comes with the following condition, after the year is changed temporarily: (Here's my current idea of the logic)
- If date X is earlier than today, then difference = datediff(X,now), with the X year is current year
- If date X is later than today, then difference = datediff(X,now), with the X year is one year before
Sample case:
1st case: The input date is 6-6-1990. Today (automatically generated) is 22-8-2011. Then the difference will be = datediff(6-6-2011,22-08-2011)
2nd case: The input date is 10-10-1990. Today (automatically generated) is 22-8-2011. Then the difference will be = datediff(10-10-2010,22-08-2011)
Any idea how to do this in SQL (in SQL Server)? Or is there any other more simple alternatives for this problem? I'd also like this to be done in the query and not using a stored procedure or function
Sorry if there's already a similar question, I just don't know the exact keyword for this problem :( if there's a question like this previously, feel free to direct me there.
Thanks in advance
Here is the implementation (if I understood the logic you need correctly):
USE YourDbName
GO
CREATE FUNCTION YearPartDiff (#date datetime)
RETURNS int
AS
BEGIN
DECLARE #dateCurrentYear datetime
SET #dateCurrentYear = DATEADD(year, YEAR(GETDATE()) - YEAR(#date), #date)
DECLARE #result int
IF #dateCurrentYear < GETDATE()
SET #result = ABS(DATEDIFF(day, #dateCurrentYear, GETDATE()))
ELSE
SET #result = ABS(DATEDIFF(day, DATEADD(year, -1, #dateCurrentYear), GETDATE()))
RETURN(#result)
END
GO
And the example of usage:
USE YourDbName
GO
DECLARE #someDate datetime
SET #someDate = '2011-06-06'
SELECT dbo.YearPartDiff(#someDate) /*returns 77*/
SET #someDate = '2010-10-10'
SELECT dbo.YearPartDiff(#someDate) /*returns 316*/
Basically, #Andrei's solution, but in a single statement:
SELECT
DayDiff = DATEDIFF(
DAY,
DATEADD(YEAR, CASE WHEN LastOcc > GETDATE() THEN -1 ELSE 0 END, LastOcc),
GETDATE()
)
FROM (
SELECT LastOcc = DATEADD(YEAR, YEAR(GETDATE()) - YEAR(#InputDate), #InputDate)
) s
This seems to do the job
SELECT DATEDIFF(DAY, CONVERT(DATETIME, N'2011-06-06'), CONVERT(DATETIME, N'2011-08-22'))
So the basic syntax is
SELECT DATEDIFF(DAY, CONVERT(DATETIME, N'yyyy-mm-dd'), CONVERT(DATETIME, N'yyyy-mm-dd '))
Alternatively, you can use GETDATE() instead of the string for today's date
I have used "SELECT DATEDIFF( D, "+myDate+", GETDATE())" in my code, on SQL Server 2005. It works for me. The value myDate of course would be the DateTime input value.
you should try this query:
create table #T (inp_date datetime)
insert #T values ('06-06-1990')
insert #T values ('08-22-1990')
insert #T values ('10-10-1990')
--select * from #T
select inp_date, GETDATE(),
CASE
WHEN DATEADD(yy,DATEDIFF(yy,inp_date,GETDATE()),inp_date) <= GETDATE()
THEN DATEDIFF(dd,DATEADD(yy,DATEDIFF(yy,inp_date,GETDATE()),inp_date),GETDATE())
ELSE DATEDIFF(dd,DATEADD(yy,DATEDIFF(yy,inp_date,GETDATE())-1,inp_date),GETDATE())
END
from #T

Most efficient way to calculate the first day of the current Financial Year?

What's the most efficient way to calculate the first day of the current (Australian) Financial Year?
The Australian FY begins on 01-July.
E.g.
SELECT dbo.FinancialYearStart('30-Jun-2011') returns 01-Jul-2010.
SELECT dbo.FinancialYearStart('01-Jul-2011') returns 01-Jul-2011.
SELECT dbo.FinancialYearStart('02-Jul-2011') returns 01-Jul-2011.
One DATEADD, one DATEDIFF, and a division:
SELECT DATEADD(year,DATEDIFF(month,'19010701','20110630')/12,'19010701')
Basically, you count the number of months since some arbitrary financial year's start date (I've picked 1901), divide that number by 12 (ignoring the remainder), and add that many years back to the same arbitrary year's start date.
I don't know if this is the most efficient, but it's fast at least...
create function dbo.FinancialYearStart
(
#CurrentDate datetime
)
returns datetime
as
begin
declare #CurrentYear int
,#FYDateThisYear datetime
,#FYDatePrevYear datetime
set #CurrentYear = datepart(year, #CurrentDate)
set #FYDateThisYear = '01-Jul-' + cast(#CurrentYear as varchar(4))
set #FYDatePrevYear = '01-Jul-' + cast(#CurrentYear-1 as varchar(4))
if #CurrentDate < #FYDateThisYear
begin
return #FYDatePrevYear
end
return #FYDateThisYear
end
Extract the year and month from the date. Then do year = year + FLOOR((month-7) / 6)
Then your date is 1-jul-year
(You don't actually need to store them as variables.)
Something like: CONCATENATE('01-jul-', YEAR(date) + FLOOR((MONTH(date)-7) / 6)
A somewhat sophisticated method (maybe a tiny little bit too much):
SELECT
DATEADD(month,
(MONTH(GETDATE()) - 1) / 6 * 12 - 6,
CAST(CAST(YEAR(GETDATE()) AS varchar) AS datetime)
)
Clunky but it works
select
cast('01-Apr-' +
cast(
case
when datepart(mm,getdate()) in (4,5,6,7,8,9,10,11,12)
then DATEPART(yy,getdate())
else DATEPART(yy,getdate())-1
end as varchar
) as datetime
) as fy_start
SELECT cast(cast(YEAR(getdate())-
(case
when MONTH(GETDATE()) between 1 and 6 then 1
else 0
end) as varchar)+'0701' as date)