On Teradata SQL I am trying to convert the duration 30 hours and 30 minutes given as '3030' to 1) 30:30 and 2) 30.5 . Or, in another example 3 hours and 15 minutes as 1) 3:10 and 3) 3.25
I can use mod and other arithmetic operations. However, is there a default way of doing this in Teradata SQL?
Every interval has a FORMAT
select format(interval '3:30' hour to minute)
returns
-h(1):mm
but I never found a way to change it :-(
Assuming that you input is a string:
cast(col as int) / 100 + to_number(col) mod 100 / 60 -- numeric result
trim(cast(col as int format 'Z(8)9:99')) -- string result
You can just insert the character:
select substr(val, 1, 2) || ':' substr(val, 3, 2)
Or, convert the values to integers:
select cast(substr(val, 1, 2) as decimal(10, 2)) + cast(substr(val, 3, 2) as decimal(10, 2))/60.0
EDIT:
If you want to convert them to a number, you can do:
select (cast(hhmm as int) / 100 + (cast(hhmm as int) mod 100) / 60.0
This will return a number.
Related
I have a set of integer value which can be either a single digit to 6 digit number. Now I want to convert this set of values to time representing the HH:MM:SS format. I thought of converting first to varchar then to time but it didn't work out. Can anyone help me out with the problem?
You can use TIMEFROMPARTS
SELECT
TIMEFROMPARTS(
YourColumn / 10000,
YourColumn / 100 % 100,
YourColumn % 100
)
FROM YourTable;
This happens to be what run times look like in msdb..sysjobschedules, which I've addressed here. Assuming "val" is your integer, try:
select dateadd(s, val - ((val / 100) * 40) - ((val / 10000) * 2400), 0/*or some date*/)
(subtracting out 40 seconds per minute and 40*100 + 2400 seconds per hour to get the actual number of seconds, then adding that many seconds to a date.)
Try:
date (dateadd(second,value,'19700101'))
This question already has answers here:
Most efficient method for adding leading 0's to an int in sql
(5 answers)
Closed 7 months ago.
I have date and time values that are stored (separately) as integers.
I now want to convert them into datetime data type into a new column but have trouble handling the time.
My first idea was to do it kinda like this (I can deal with the dates so in this example I'm just using a dummy date):
SET new_column = CAST(CONCAT('2020-01-01T',
date_column / 10000, ':',
date_column % 10000 / 100, ':',
date_column % 100) AS DATETIME)
The issue is that CAST expects exactly the format 'yyyy-mm-ddThh:mm:ss' but the calculation may sometimes only return one digit instead of the needed two digits for a part of the time.
For example the time one minute after 9am would result in the string '2020-01-01T9:1:0' though '2020-01-01T09:01:00' would be required.
Is there an efficient way to add leading 0s?
EDIT: The date_column contains integer values that represent times in the format hhmmss. So for example 10am would be stored as 100000, one minute after 9am would be stored as 90100.
I know that it is stupid to encode times/dates as integer. This is for legacy reasons and my current task is to fix it ;)
You need to pad with a zero to deal with single-digit output. Unfortunately, T-SQL doesn't have a PAD or RPAD function, so you have to do it manually:
SET new_column = CONVERT(datetime,
CONCAT('2020-01-01T',
RIGHT(CONCAT('0', date_column / 10000),2)
+ ':'
+ RIGHT(CONCAT('0', date_column % 10000 / 100), 2)
+ ':'
+ RIGHT(CONCAT('0', date_column % 100), 2)));
Example db<>fiddle
Instead of worrying about creating a string to be converted - convert the time to seconds and just add that to your date:
Declare #myDate int = 20220711
, #myTime int = 182233;
Select cast(#myDate As char(10))
, #myTime / 10000 * 60 * 60
, #myTime % 10000 / 100 * 60
, #myTime % 100
, dateadd(second, (#myTime / 10000 * 60 * 60) + (#myTime % 10000 / 100 * 60) + (#myTime % 100), cast(#myDate As char(10)))
I need to extact fractional part of double in sql, but without "0." For example:
number: 5.67
int: 5
fact: 67
In most databases, you can use something like this:
select cast((x - floor(x)) * 100 as int)
In SQL Server, you have other options. For instance, to get the fractional part, you can use %:
select (x % 1)
To get two digits:
select floor(100 * (x % 1)) -- or perhaps round()
or:
select (x * 100) % 100
SELECT 5.67 AS Doubles, CAST(5.67 AS INT) AS Fractional_Only,
PARSENAME(5.67,1) AS DECIMAL_ONLY
this will work in oracle:
select substr(to_char(5.67),instr(to_char(5.67),'.')+1) from dual;
check http://sqlfiddle.com/#!4/e2ac5e/1074
for mssql :
select substring(CONVERT(varchar, 25.65),CHARINDEX('.', CONVERT(varchar, 25.65))+1,5);
http://sqlfiddle.com/#!18/9eecb/41866
check the last one :
select substring(CONVERT(varchar, (15+15)/2.0),
CHARINDEX('.', CONVERT(varchar, (15+15)/2.0))+1,1);
http://sqlfiddle.com/#!18/9eecb/41875
I Have Minutes as 1064 in a column called 'Efforts_in_minutes' and I need the Output in the format of HH:MM (i.e) 17:44. I have tried the below Query
SELECT Cast(Round(Total_Effort_in_Minutes / 60, 0, 2) AS VARCHAR)
+ ':'
+ Cast(Total_Effort_in_Minutes % 60 AS VARCHAR(2))
FROM PPS
I got the output as 17.000000:44 but What i Need is 17:44
Please advice how to achieve that.
The use of the Round function is unnecessary. Just do integer division:
select CAST(CAST(Total_Effort_in_Minutes AS INT) / 60 AS VARCHAR)
+ ':' + CAST(Total_Effort_in_Minutes % 60 AS VARCHAR(2) )
If your column Total_Effort_in_Minutes already has an integer data type, then you can simplify to:
select CAST(Total_Effort_in_Minutes / 60 AS VARCHAR)
+ ':' + CAST(Total_Effort_in_Minutes % 60 AS VARCHAR(2) )
If you need the minute part to be left-padded with zero to get at least 2 digits, then:
select RIGHT('0' + CAST(CAST(Total_Effort_in_Minutes AS INT) / 60 AS VARCHAR), 2)
+ ':' + CAST(Total_Effort_in_Minutes % 60 AS VARCHAR(2) )
SELECT DATEADD(MI,Total_Effort_in_Minutes,TIMEFROMPARTS(0,0,0,0,0))
FROM PPS
Best practice: The client should decide how to represent the time based on the locale, to allow for variants such as 24H clock vs AM/PM.
Please see this link: https://stackoverflow.com/a/19887500/6298495
Creating an inline function is a good solution provided in the link.
Just for fun:
SELECT CONVERT(CHAR(5), DATEADD(mi, 1064, 0), 8)
Part of the task I have been given involves performing calculations on a few columns, 2 of which are in the format of hh.mi.ss and they're varchar. In order for the calculations to work, I need to get them into a time decimal format, whereby 1:30 would be 1.5 . Since I'm currently using SQL Server 2005, I don't have the time or data types built-in and I'm unable to get an upgraded version (not my choice). Working with what I have, I've searched around online and tried to convert it but the result isn't accurate. For example, 13.28 becomes (roughly) 13.5, which is great, however, the seconds go to 100 instead of ending at 60 (since I'm converting it to a float).
For example, using 12.57.46,
CAST(DATEPART(HH, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME)) AS FLOAT) +
(CAST(DATEPART(MI, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME)) AS FLOAT)/60) +
(CAST(DATEPART(SS, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME)) AS FLOAT)/3600)
gave me 12.962...
whereas
CAST(SUBSTRING([OASTIM], 1, 2) AS FLOAT) +
((CAST(SUBSTRING([OASTIM], 4, 5) AS FLOAT) +
CAST(SUBSTRING([OASTIM], 7, 8) AS FLOAT)/60)/60)
gave me 12.970....
and when I tried something simpler,
DATEPART(HOUR, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME))+
(DATEPART(MINUTE, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME))/60)
flopped out and gave me only 12
It's my first exposure to Windows SQL and T-SQL, I've been struggling with this for a few hours. As horrible as it sounds, I'm at the point where I'd be happy with it working even it it means sacrificing performance.
You don't explain what "time decimal" format is. From your example, I'll guess that you mean decimal hours.
A key function in SQL Server for date differences is datediff(). You can convert the time to seconds using a trick. Add the time to a date, then use datediff() to get the number of seconds after midnight. After that, the conversion to decimal hours is just arithmetic.
Here is an example:
select datediff(second,
cast('2000-01-01' as datetime),
cast('2000-01-01 ' + '00:00:59' as datetime)
)/3600.0 as DecimalHours
Note the use of the constant 3600.0. The decimal point is quite important, because SQL Server does integer division on integer inputs. So, 1/2 is 0, rather than 0.5.
You said,
CAST(SUBSTRING([OASTIM], 1, 2) AS FLOAT) +
((CAST(SUBSTRING([OASTIM], 4, 5) AS FLOAT) +
CAST(SUBSTRING([OASTIM], 7, 8) AS FLOAT)/60)/60)
gave me 12.970....
12.970 is wrong for an input of '12.57.46'. The problem is that you are using the SUBSTRING function incorrectly. The 3rd argument represents the number of characters, not the ending character position.
Take a look at this code:
Declare #Sample varchar(20)
Set #Sample = '12.57.46'
select CAST(SUBSTRING(#Sample, 1, 2) AS FLOAT) +
CAST(SUBSTRING(#Sample, 4, 5) AS FLOAT) / 60 +
CAST(SUBSTRING(#Sample, 7, 8) AS FLOAT) / 60 / 60,
SUBSTRING(#Sample, 1, 2),
SUBSTRING(#Sample, 4, 5),
SUBSTRING(#Sample, 7, 8),
CAST(SUBSTRING(#Sample, 1, 2) AS FLOAT) +
CAST(SUBSTRING(#Sample, 4, 2) AS FLOAT) / 60 +
CAST(SUBSTRING(#Sample, 7, 2) AS FLOAT) / 60 / 60
Notice that the minutes is coming out as 57.46 because you are asking for 5 characters. The seconds are coming out correctly because eventhough you are asking for 8 characters, there are only 2 characters left in the string so only those 2 characters are returned.
BTW, I would solve this problem the same way that Gordon did, except I would remove the date stuff so it would look like this:
Select DateDiff(Second,
0,
Convert(DateTime, Replace([OASTIM], '.',':'))) / 3600.0
Here is a simple way to convert time to DecimalHours.
SELECT cast(cast('12.57:46' as datetime) as float) * 24
Result:
~12.963