How to modify year with a Cast Statement in Sql - 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

Related

CONVERT is presenting the wrong year

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.

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)

Get current year in TSQL

I have data I am trying to pull for a report and I am working on a Year to Date report. My columns in the table are formatted as datetime. I am trying to run a select statement to get all the results where date = this year.
For example:
SELECT A.[id], A.[classXML]
FROM tuitionSubmissions as A
WHERE A.[status] = 'Approved' AND A.[reimbursementDate] = THISYEAR
FOR XML PATH ('data'), TYPE, ELEMENTS, ROOT ('root');
Is there an eay way to acomplish this?
Yes, it's remarkably easy in fact:
WHERE YEAR(A.[reimbursementDate]) = YEAR(GETDATE())
This should be a better way if performance is an issue (although it isn't as readable)
where A.[reimbursementDate] between
DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0) and
DATEADD(MILLISECOND, -3, DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) + 1, 0))
Those funky DATEADD statements return the first and last days of the current year (through December 31 23:59:59.997). Since reimbursementDate isn't contained in a function, the query will be able to take advantage of any applicable indexes.

sql compare datetime today

I hope anyone can translate my abstract query.
I want to select * from TABLE where ( [MYDATETIMEROW] < (TODAY - 3 Days)).
Does I have to Convert, cast or use datepart or anything else?.. im confused.
Are there simple rules? I would'nt have problems to do that with linq but simple sql I learned just hardly.
Thank you and best regards.
In simple terms:
Select * from Table where MyDateTimeRow < dateadd(dd,-3,getdate())
But using getdate() will provide both a date and a time, experience says that this is unlikely to be exactly what you want - you might want to strip the time down and just consider the date portion
Select * From Table where MyDateTimeRow < dateadd(dd, datediff(dd, 0, getdate()) - 3, 0)
You want the DateAdd function to manipulate dates and the GetDate function to get the current date:
SELECT * FROM MyTable WHERE [MyDateTimeRow] < DateAdd(dd, -3, GetDate())

MS SQL Date Only Without Time

Question
Hello All,
I've had some confusion for quite some time with essentially flooring a DateTime SQL type using T-SQL. Essentially, I want to take a DateTime value of say 2008-12-1 14:30:12 and make it 2008-12-1 00:00:00. Alot of the queries we run for reports use a date value in the WHERE clause, but I either have a start and end date value of a day and use a BETWEEN, or I find some other method.
Currently I'm using the following:
WHERE CAST(CONVERT(VARCHAR, [tstamp], 102) AS DATETIME) = #dateParam
However, this seems kinda clunky. I was hoping there would be something more simple like
CAST([tstamp] AS DATE)
Some places online recommend using DATEPART() function, but then I end up with something like this:
WHERE DATEPART(year, [tstamp]) = DATEPART(year, #dateParam)
AND DATEPART(month, [tstamp]) = DATEPART(month, #dateParam)
AND DATEPART(day, [tstamp]) = DATEPART(day, #dateParam)
Maybe I'm being overly concerned with something small and if so please let me know. I just want to make sure the stuff I'm writing is as efficient as possible. I want to eliminate any weak links.
Any suggestions?
Thanks,
C
Solution
Thanks everyone for the great feedback. A lot of useful information. I'm going to change around our functions to eliminate the function on the left hand side of the operator. Although most of our date columns don't use indexes, it is probably still a better practice.
If you're using SQL Server 2008 it has this built in now, see this in books online
CAST(GETDATE() AS date)
that is very bad for performance, take a look at Only In A Database Can You Get 1000% + Improvement By Changing A Few Lines Of Code
functions on the left side of the operator are bad
here is what you need to do
declare #d datetime
select #d = '2008-12-1 14:30:12'
where tstamp >= dateadd(dd, datediff(dd, 0, #d)+0, 0)
and tstamp < dateadd(dd, datediff(dd, 0, #d)+1, 0)
Run this to see what it does
select dateadd(dd, datediff(dd, 0, getdate())+1, 0)
select dateadd(dd, datediff(dd, 0, getdate())+0, 0)
The Date functions posted by others are the most correct way to handle this.
However, it's funny you mention the term "floor", because there's a little hack that will run somewhat faster:
CAST(FLOOR(CAST(#dateParam AS float)) AS DateTime)
CONVERT(date, GETDATE()) and CONVERT(time, GETDATE()) works in SQL Server 2008. I'm uncertain about 2005.
How about this?
SELECT DATEADD(dd, DATEDIFF(dd,0,GETDATE()), 0)
Yes, T-SQL can feel extremely primitive at times, and it is things like these that often times push me to doing a lot of my logic in my language of choice (such as C#).
However, when you absolutely need to do some of these things in SQL for performance reasons, then your best bet is to create functions to house these "algorithms."
Take a look at this article. He offers up quite a few handy SQL functions along these lines that I think will help you.
http://weblogs.sqlteam.com/jeffs/archive/2007/01/02/56079.aspx
Careful here, if you use anything a long the lines of WHERE CAST(CONVERT(VARCHAR, [tstamp], 102) AS DATETIME) = #dateParam it will force a scan on the table and no indexes will be used for that portion.
A much cleaner way of doing this is defining a calculated column
create table #t (
d datetime,
d2 as
cast (datepart(year,d) as varchar(4)) + '-' +
right('0' + cast (datepart(month,d) as varchar(2)),2) + '-' +
right('0' + cast (datepart(day,d) as varchar(2)),2)
)
-- notice a lot of care need to be taken to ensure the format is comparable. (zero padding)
insert #t
values (getdate())
create index idx on #t(d2)
select d2, count(d2) from #t
where d2 between '2008-01-01' and '2009-01-22'
group by d2
-- index seek is used
This way you can directly check the d2 column and an index will be used and you dont have to muck around with conversions.
DATEADD(d, 0, DATEDIFF(d, 0, [tstamp]))
Edit: While this will remove the time portion of your datetime, it will also make the condition non SARGable. If that's important for this query, an indexed view or a between clause is more appropriate.
Alternatively you could use
declare #d datetimeselect
#d = '2008-12-1 14:30:12'
where tstamp
BETWEEN dateadd(dd, datediff(dd, 0, #d)+0, 0)
AND dateadd(dd, datediff(dd, 0, #d)+1, 0)
Here's a query that will return all results within a range of days.
DECLARE #startDate DATETIME
DECLARE #endDate DATETIME
SET #startDate = DATEADD(day, -30, GETDATE())
SET #endDate = GETDATE()
SELECT *
FROM table
WHERE dateColumn >= DATEADD(day, DATEDIFF(day, 0, #startDate), 0)
AND dateColumn < DATEADD(day, 1, DATEDIFF(day, 0, #endDate))
FWIW, I've been doing the same thing as you for years
CAST(CONVERT(VARCHAR, [tstamp], 102) AS DATETIME) = #dateParam
Seems to me like this is one of the better ways to strip off time in terms of flexibility, speed and readabily. (sorry). Some UDF functions as suggested can be useful, but UDFs can be slow with larger result sets.
WHERE DATEDIFF(day, tstamp, #dateParam) = 0
This should get you there if you don't care about time.
This is to answer the meta question of comparing the dates of two values when you don't care about the time.