How to add a number to a year TSQL - sql-server

I want to add a number to my date
For example I have column F9 which contains a date 2015.10.17 and I have a column F49 that has a number in it 10.
The end result should be 2025.10.17 so the number should only be added to the year and that’s it.
All three columns are of typ varchar
I have tried to do it as simple as possible but that does not work
UPDATE A.dbo.B
SET F29 = F9 + F49

If column type Data/datetime
UPDATE A.dbo.B SET F29 = DATEADD(year,F49,F9)
or this
F29 = CAST(CAST(SUBSTRING(F9,1,4) as INT) + F49 as VARCHAR(4)) + SUBSTRING(F9,5,LEN(F9))

Use DATEADD like below
UPDATE A.dbo.B
SET F29 = dateadd(year,F49,F9)

Test the functionality using below script:
DECLARE #Table TABLE (F9 VARCHAR(20), F49 VARCHAR(10))
INSERT INTO #Table VALUES ('2015.10.17', '10')
SELECT DATEADD(YEAR, CAST(t.F49 AS INT), CAST(t.F9 AS DATETIME))
FROM #Table AS t
And finally use following script to update:
UPDATE A.dbo.B
SET F29 = DATEADD(YEAR, CAST(t.F49 AS INT), CAST(t.F9 AS DATETIME))

Use roughly the exact same logic discussed in your previous question. You convert the F9 column as before, apply the dateadd function to it to add F49 as years, and then convert the result back to char(10) using the appropriate format. OR you could just fix your schema and never have to deal with these self-created problems.

Related

TSQL Convert String to Year only

I have the following table:
SELECT * FROM [dbo].[Dimension_Game_Developer]
Table Schema:
Sample Data of select statement output:
I am trying to convert the string date as Year only date using the following:
update [dbo].[Dimension_Game_Developer]
SET [Year_of_Release] = CAST([Year_of_Release] as DATE)
How would I make that change? Perhaps convert is better the CAST for this?
You need to cast Year_of_Release as int as shown below.
update [dbo].[Dimension_Game_Developer]
SET [Year_of_Release] = CAST(Convert(Varchar(4), [Year_of_Release]) as int)
You can also convert it to float.
update [dbo].[Dimension_Game_Developer] SET [Year_of_Release] =
CAST([Year_of_Release] as float)
To solve the issue permanently you should updated the datatype of column Year_of_Release to int and insert the value in the integer further.
To change the column datatype:
ALTER TABLE [dbo].[Dimension_Game_Developer] ALTER COLUMN Year_of_Release int;
to format values ​​without the need for cast and substring
use the function Call Format o try_cast
example:
DECLARE #d DATETIME = '10/01/2011';
declare #tab table (StartDate date, year varchar(6),val1 int,val2 int)
insert into #tab(StartDate,year,val1,val2) values('2014-02-15','2015.0',0,0)
insert into #tab(StartDate,year,val1,val2) values('2015-02-15','2016.0',0,0)
insert into #tab(StartDate,year,val1,val2) values('2016-02-15','2017.0',0,0)
insert into #tab(StartDate,year,val1,val2) values('2017-02-15','2018.0',0,0)
update #tab SET [val1] = FORMAT ( StartDate, 'yyyy'),[val2] =try_cast(year as decimal(18,0))
select * from #tab
these two functions can be found in the sql server documentation
try DatePart(year,CAST([Year_of_Release] as DATE)) Year

Convert VARCHAR in format YYMMDD to YYYYMMDD and ignore invalid date formats

I have a table with a VARCHAR field called ArrivalDate in format yymmdd (such as 170202).
I am writing a query which converts it to yyyymmdd so it should become 20170202.
However my problem is that I need to cater for the case when inappropriate data is entered into the field, and my query needs to exclude that data. I am achieving this exclusion by using the ISDATE function of TSQL. I also need to select the least recent entry (I'm using order by asc for this).
I am using a variety of converts to write this query, below is my implementation with a sample table and data.
Declare #tmp TABLE (theDates VARCHAR(MAX))
INSERT INTO #tmp VALUES('170202')
SELECT TOP 1 t.theDates
WHEN (ISDATE(t.theDates) = 1) THEN CONVERT( VARCHAR(max),CONVERT(datetime t.theDates), 112)
FROM #tmp t
WHERE (ISDATE(t.theDates) = 1)
ORDER BY CAST(t.theDates as DATE)
However I do not like my approach and it occasionally fails conversion and throws an error with values such as 02/02/02 which breaks the query. Can someone please show me a better way of writing this functionality.
Much appreciated!
You can use TRY_CONVERT and CONVERT to get the correct format and convert the value. Then check that the string is exactly 6 character to prevent other formats from being returned.
SELECT
convert(char(10),convert(date, theDates, 12),112)
FROM
(values('02/02/02'),('170202')) x(theDates)
WHERE
try_convert(date, theDates, 12) is not null
and len(theDates) = 6
You can use cast(#date as datetime)
declare #date varchar(max);
set #date='170202';
select
CASE WHEN (ISDATE(cast(#date as datetime)) = 1)
THEN CONVERT(VARCHAR(max), CONVERT(datetime, cast(#date as datetime)), 112) end
from table
set #date='02/02/02';
select
CASE WHEN (ISDATE(cast(#date as datetime)) = 1)
THEN CONVERT(VARCHAR(max), CONVERT(datetime, cast(#date as datetime)), 112) end
from table
please use create function for check dateformat is Valid or not and use this fun in your query inside cash clouse.
ALTER FUNCTION dbo.f_CheckDate
(#InDate nvarchar(25))
RETURNS DATE
AS
BEGIN
declare #Return DATETIME
select #return = CASE WHEN ISDATE(#InDate) = 1
THEN #InDate
ELSE NULL
END
return #return
END
You could use TRY_CAST or TRY_CONVERT if value cannot be cast it will return NULL.
SELECT
TRY_CAST('20170228' AS DATETIME),
TRY_CAST('170228' AS DATETIME),
TRY_CONVERT(DATETIME, '20170228'),
TRY_CONVERT(DATETIME, '170228')
This works for SQL Server 2012 and newer.

I need to update age in SQL Server 2008 according to DOB

I have a table in SQL Server 2008, which has DOB (e.g. 1992-03-15) and in same table, I have an Age column, which is right now Null. I need to update the Age according to the DOB. I have both columns (AGE and DOB) in the same table. I need script which does my job to update Age according to DOB
And other one is in same table, I have Arrival Month (e.g. 8) and Arrival year (e.g. 2011), according to that I need to update another column (Time in country). Say let's say according to example (08(MM), 2011(YYYY)), should update (TimeInCountry) - 4.2 something like that. Which should deduct from current date and time has mentioned into month and year
Do let me know if you need anything else.
Not sure what is the data type your age column is
You can do something like below
Update TableName
Set Age = DATEDIFF(yy, DOB, getdate())
if you using decimal
Age = DATEDIFF(hour,DOB,GETDATE())/8766.0
I believe creating a trigger bill be use full, if you adding new rows in future
For yopur first Problem,
UPDATE TABLE_NAME SET AGE=DATEDIFF(hour,DOB_COLUMN,GETDATE())/8766.0
If you want in Round ,
UPDATE TABLE_NAME SET
AGE= CONVERT(int,ROUND(DATEDIFF(hour,DOB_COLUMN,GETDATE())/8766.0,0))
And Not Sure what you really want to do in the Second Problem,but my guess you can try something like..
Update Table_Name set
TimeInCountry=cast(len(Arrival_year) as varchar(4))+'.'+cast(len(Arrival_Month) as varchar(2))
I have implemented User Defined function
Here it is which may help to someone.
ALTER FUNCTION [dbo].[TimeInCountry]
(
#ArrivalMonth varchar(10),
#ArrivalYear Varchar(10)
) RETURNS VARCHAR(10)
BEGIN
Declare #Ageyear int
Declare #Agemonth int
Declare #Final varchar(10)
Declare #CurrentMonth int
Declare #Currentyear int
Set #CurrentMonth = (Select DatePart(mm, GetDate()))
Set #Currentyear = (Select DatePart(yyyy,GetDate()))
Select #AgeYear = #Currentyear - #ArrivalYear
Select #AgeMonth = #CurrentMonth - #ArrivalMonth
if (#AgeMonth < 0)
BEGIN
Set #AgeYear = #AgeYear - 1
Set #AgeMonth = #AgeMonth + 12
END
Select #Final = (Select Cast(#AgeYear as Varchar(max)) +'.'+ Cast(#AgeMonth as varchar(max)))
Return #Final
---And finally call this function where to update.
--To Check
Select [DBName].TimeInCountry (8,2013)
--- and Finally updating.
Update [DBName].[dbo].[TableName] Set TimeInCountry = dbo.TimeInCountry (ArrivalMonth,ArrivalYear) from [DBName].[dbo].[TableName]
Thanks again everyone.

T-SQL date conversion

I have the following date format 92845 which represent hhmmss.
I would like to convert that to a datetime in SQL.
I could use something like this:
SELECT STUFF(STUFF('84936',3,0,'-'),6,0,'-')
but it appears T-SQL is not liking the hour part.
thank you!
Seems like you wrote the code in the afternoon and now it doesn't work in the morning. If you're going to stuff based on absolute positioning, you need to make sure the string is always the same length. One way to do this is by padding the string with a 0 and then taking the right-most 6 characters. Also, you need : not - for H/M separators.
SELECT STUFF(STUFF(RIGHT('0' + '84936', 6),3,0,':'),6,0,':');
Result:
08:49:36
Now it can be converted to a datetime:
SELECT CONVERT(DATETIME, STUFF(STUFF(RIGHT('0' + '84936', 6),3,0,':'),6,0,':'));
Result:
1900-01-01 08:49:36.000
I don't know where 92845 is currently stored. If it's in a variable, then something like this will work:
declare #t varchar(6) = '92845';
declare #fullt char(6) = RIGHT('000000' + #t,6)
select DATEADD(second,
SUBSTRING(#fullt,1,2) * 3600 +
SUBSTRING(#fullt,3,2) * 60 +
SUBSTRING(#fullt,5,2),0)
Result:
1900-01-01 09:28:45.000
If it's in a column of a result set, then you can do similar manipulations using e.g. subqueries.
try this:
declare #t varchar(6) = '134524'
select CASE WHEN len(#t)=5 then convert(datetime,convert(varchar(10),CAST(getdate() as date))+' '+'0'+LEFT(#t,1)+':'+SUBSTRING(#t,2,2)+':'+SUBSTRING(#t,4,2))
else convert(datetime,convert(varchar(10),CAST(getdate() as date))+' '+LEFT(#t,2)+':'+SUBSTRING(#t,3,2)+':'+SUBSTRING(#t,5,2)) end

SQL convert int to time

I have a database that displays time as an integer. However I am wanting to output this into a report with the correct format. This is the format that I would like to change:
eg.
183000 would become 18:30
500 would become 00:05
160000 would become 16:00
and so on.
I have had a look and CAST and CONVERT but not successfully managed to get this the time in the correct format.
Assuming your input will always be an int, you can parse it with something like:
DECLARE #stringTime varchar(6)
SET #stringTime = RIGHT('000000' + CAST(intTime AS VARCHAR), 6)
SELECT CAST(LEFT(#stringTime, 2) + ':' + RIGHT(LEFT(#stringTime, 4), 2) AS TIME) as TimeValue
I'd DEFINITELY look to change this field to an actual time or datetime field, as this level of conversion is not advised, especially for a heavily used database. There's just really got to be a better way to store your data.
Using an int value this way allows for a lot of bad data, without adding a lot of additional checks and/or constraints on your inputs (i.e.: 260000, 127900, etc.)
looks like you need to divide by 100 to get the seconds, divide by 10000 to get the minutes, and divide by 1000000 to get the hours, then format those values as a string, inserting a colon between hours and minutes, like
hh:mm
First cast to a varchar field and convert all times to 4 digits adding leading zeros if need be (500 would become 0500)and then break up the field with concantenation Left(myfield,2) + ':' + right(myfield,2)
This is something stupid to do every time you run a report, it is wasteful of server resources. If possible change the field to varchar and runthe code once. If not possible, can you add a formatted field and have a trigger do the formatiing on insertion (you'll still need to update the field the first time? Possibly a constraint would do instead of a trigger, but that would depend on the database.
I'm assuming that you are on SQL Server based on use of CONVERT and your previous questions.
You could use DATEADD for this too.
WITH Times AS
(
SELECT 183000 AS T
UNION ALL
SELECT 500
UNION ALL
SELECT 160000
)
SELECT CAST(DATEADD(SECOND, T%100 + (60*(T%10000 / 100)) + 3600*(T/10000),0)
AS time /*Or datetime if < SQL Server 2008*/)
FROM Times
declare #i int = 235959
select cast(stuff(stuff(
case when len(cast(#i as varchar(6))) = 6 then cast(#i as varchar(6))
else REPLICATE('0',6 - LEN(cast(#i as varchar(6))))+cast(#i as varchar(6))
end
,3,0,':'), 6, 0,':') as datetime)
set #i = 500
select cast(stuff(stuff(
case when len(cast(#i as varchar(6))) = 6 then cast(#i as varchar(6))
else REPLICATE('0',6 - LEN(cast(#i as varchar(6))))+cast(#i as varchar(6))
end
,3,0,':'), 6, 0,':') as datetime)
DECLARE #intTime int
SET #intTime = 50000
SELECT CAST(STUFF(STUFF(CONCAT(REPLICATE('0', 6 - LEN(#intTime)),#intTime),3,0,':'),6,0,':') AS TIME(0))
ALTER FUNCTION [dbo].[MinutesToDuration]
(
#minutes int
)
RETURNS nvarchar(30)
AS
BEGIN
declare #hours nvarchar(20)
DECLARE #XX NVARCHAR(10)
DECLARE #HH VARCHAR(2)
DECLARE #TT VARCHAR(2)
DECLARE #BL NVARCHAR(2)
DECLARE #TM VARCHAR(5)
SET #XX=#minutes
IF #XX<60
BEGIN
IF #XX<10
BEGIN
SET #HH='00'
SET #TT='0'+#XX
END
ELSE
BEGIN
SET #HH='00'
SET #TT=#XX
END
END
ELSE
BEGIN
IF #XX%60=0
BEGIN
SET #HH=#XX/60
SET #TT='00'
END
ELSE
BEGIN
SET #BL= #XX%60
IF #BL<10
BEGIN
SET #HH=#XX/60
SET #TT='0'+#BL
END
ELSE
BEGIN
SET #HH=#XX/60
SET #TT=#BL
END
END
END
SET #hours= #HH+':'+#TT
return #hours
END

Resources