CONVERT is presenting the wrong year - sql

I'm using SQL Server 2014, and I'm trying to perform a data conversion, the value being passed '04-SEP-44'
Since this was the birth year, it needs to be 1944, not 2044.
I've tried
select convert(DATETIME, '04-SEP-44')
select convert(DATETIME, '04-SEP-44', 1)
select convert(DATETIME, '04-SEP-44', 13)
But they are all using the year as 2044.
Are there any quick fixes to this issue?

Possibilities:
If the value is greater than today subtract 100 years...
Force "19" into the string...
But it really depends on your business rules, is it always going to be 1900, or could some dates be early 2000's? You should really update your front end to capture the full date.
select case when Y.[Value] > getdate() then dateadd(year, -100, Y.[Value]) else Y.[Value] end
, convert(date, substring(X.[Value], 1, 7) + '19' + substring(X.[Value], 8, 2))
from (values ('04-SEP-44')) as X ([Value])
cross apply (values (convert(date, X.[Value]))) as Y ([Value]);
Note: why would you convert a date to a datetime? Don't use a datetime if you don't have a time component.

Related

column value is varchar which needs to be converted to decimal. column name is in date format. sql server

I have a table tblSample which has columns names as date format value i.e. [202007], [202006]---[202001] and datatype is varchar.
I want to update another column(X) of tblSample with [202006]-[202005] and column(Y) with [202005]-[202004].
I am using below query which is giving output as 1 for all the records(around 50 records in tblSample).
UPDATE tblSample
SET
X = CAST(ISNULL(SELECT LEFT(CONVERT(varchar, DATEADD(month, -3, GETDATE(), 112), 6)), 0) AS DECIMAL(18,2)) - CAST(ISNULL((SELECT LEFT(CONVERT(varchar, DATEADD(month, -4, GETDATE()), 112), 6)), 0) AS DECIMAL(18, 2))
I am using LEFT(CONVERT(varchar, DATEADD(month, -3, GETDATE(), 112), 6)) since the column name value will be updated everymonth to current month.
I have to convert to varchar to decimal since I am getting error saying subtraction cannot be performed on varchar values.
Where is that I am going wrong and will my update query, updates column-X and column-Y value correct for each row in the table
Values in columns of tblSample [2006]-3565.24, [2005]-3461.36, [2004]-3510.36.
Output
Thanks Shyam
You can do the update using the column names:
update tblsamples
set x = [202006]-[202005],
y = [202005]-[202004] ;
Changing names in tables is a really bad idea. You should instead have one row per month. You can then easily calculate the difference using lag():
select t.*, (value - lag(value) over (partition by ? order by yyyymm)) as diff
from t;
Perhaps re-pivoting if necessary.
If you are constructing the table each month, then you should construct the differences as well. Or, perhaps more simply, just add columns called latest_month and previous_month and use those in the update.
Finally, if you are stuck with this format, you will need to use dynamic SQL. That seems like a bad idea, though.

How to modify year with a Cast Statement in Sql

I would like to get some help with a CAST SQL Statement
From the below table sample, I would like to modify only the year from 2008 to 2016. Please keep in mind that I need this done with CAST, and not with DATEADD.
DATEADD(YEAR, 8, DATE) would be the solution but if that is not an option please utilize one of the following options.
I have left the DATEADD options in there in case they are usable after all.
DECLARE #d_date DATE = '2008-07-01'
DECLARE #v_date VARCHAR(25) = '2008-07-01'
SELECT #d_date,
#v_date,
DATEADD(YEAR, 8, #d_date),
DATEADD(YEAR, 8, CONVERT(DATE, #v_date)),
DATEADD(YEAR, 8, CAST(#v_date AS DATE)),
CAST(CAST(LEFT(#v_date, 4) AS NUMERIC) + 8 AS VARCHAR(4)) + RIGHT(#v_date, LEN(#v_date) - 4)
Please do not use the last one.
An example of Code.
http://rextester.com/NHHL75120

SQL: How to get the date yyyy/mm/dd based on the year and day number?

I have the following string 2015089 or 2016075, for example.
I need to get the result in yyyy/mm/dd format based on the given input.
So, based on 2015089, I get, 2015/mm/dd. dd is a 89th day of 2015 and mm is a month that has 89th day.
How can I do something like that?
I think the simplest way is to convert to a date using dateadd():
select dateadd(day, right(str, 3) - 1, datefromparts(left(str, 4) + 0, 1, 1) )
That is, add one less than the number of days to the beginning of the year. This assumes that Jan 1 is represented as "1" and not "0".
You can then format the date however you like.
In pre-SQL Server 2012, you can do:
select dateadd(day, right(str, 3) - 1, cast(left(str, 4) + '0101' as date))

Convert date to SQL datetime

I'm somewhat new to T-SQL and despite reading a number of articles that indicate this should work, I'm having trouble converting October 1st of the current year to a datetime.
I've tried:
SELECT CAST(DATEPART(year, GETDATE()) + '1015' AS DATETIME)
SELECT CONVERT(datetime, 'Oct 15 ' + DATEPART(YEAR,GETDATE()),100)
And all kinds of variations.
Any ideas? I need to set a datetime variable to whatever Oct 1st of the current year is.
What you're trying to is close, but DATEPART returns a number, so the "+" is doing addition, not concatenation.
Try it like this:
SELECT CAST(CAST(DATEPART(year, GETDATE()) AS VARCHAR(4)) + '1015' AS DATETIME)
edit -- Ed beat me to it, and the Concat function is better too.
But if you really wanted to knock it out of the park, try this...
SELECT DATEADD(month, 9, DATEADD(year, DATEDIFF(year, 0, getdate()), 0)) As October1CurrentYear
No casting required!
Your first query is very close. The problem is that the plus sign (+) for concatenation is actually giving you a numeric value, which you can't cast to a date.
To concatenate a year and '1015' and end up with a string, use the CONCAT function instead:
SELECT CAST(CONCAT(DATEPART(YEAR, GETDATE()), '1015') AS DATE)

How to only check the time on datetime fields but ignore the date?

I have a column that stores data in datetime format. I want to check for all instances where the time part of this column is not equal to 00:00:00:000 - the date does not matter.
Basically, if time() was a function, something like this:
SELECT *
FROM progen.DY
WHERE TIME(DY_DATE) <> '00:00:00:000'
How do I go about doing this?
You only need a minor tweak on what you already have.
SELECT *
FROM progen.DY
WHERE TIME(DY_DATE) <> '00:00:00:000'
Use CONVERT to change your DATETIME to a TIME.
SELECT *
FROM progen.DY
WHERE CONVERT(TIME, DY_DATE) <> '00:00:00:000'
Another way is to convert it to different datatype, eg
SELECT *
FROM progen.DY
WHERE CAST(DY_DATE as float) - CAST(DY_DATE as int) > 0
SQLFiddle Demo
I do this all the time when trying to see if a table's column should be turned into a date instead of a datetime, which is really the answer.
select *
from progen.dy
where cast(dy_date as Date) <> dy_date
the cast removes the time and datetime has higher precedence, so when compared, if the are unequal then it has a time value. Same thing could be done with a cast to time, with a bit of different syntax.
Use DATEDIFF and DATEADD to instead get the date part of the datetime. Compare the column against the date only, and it will return those rows that have a non-zero time.
The way this works is that we first calculate the difference (in days) between the epoch and the value. We add that number to the epoch to create a new datetime. Since the result of DATEDIFF is an integer, any time component gets rounded off.
SELECT *
FROM Table
WHERE DateColumn <> DATEADD(d, DATEDIFF(d, 0, DateColumn), 0)
The time function could then be implemented by the following, not that I recommend it for this specific scenario:
SELECT DATEDIFF(minute, DATEADD(d, DATEDIFF(d, 0, DateColumn), 0), DateColumn) as MinutesIntoDay,
-- or, if you require higher precision
DATEDIFF(second, DATEADD(d, DATEDIFF(d, 0, DateColumn), 0), DateColumn) as MinutesIntoDay
FROM Table
Edit: As mentioned in other answers, you can cast to DATE to achieve the same effect as DATEADD(d, DATEDIFF(d, 0, DateColumn), 0), which cleans up nicely. However, DATE was only added in SQL Server 2008, whereas the formula has compatibility back to at least SQL 2000. So if you need the backwards compatibility or are dealing with SQL CE, casting to DATE is unavailable.
SELECT *
FROM progen.DY
WHERE CONVERT(TIME, DY_DATE - CONVERT(DATE, DY_DATE)) > '00:00'