convert decimal to HH.MM format in SQl Server - sql

How to convert decimal to HH.MM format in SQl Server. Example:- 06.85 will be converted to 07.25, 06.60 will be converted to 7.00

SELECT
CASE
WHEN DecimalValue - FLOOR(DecimalValue) >= 0.6 THEN DecimalValue + 1 - 0.6
ELSE DecimalValue
END AS HHMMFormat
FROM
MyTable
Obviously the + 1 - 0.6 could be replaced by + 0.4 but I thought that + 1 - 0.6 more clearly showed the reason for the addition.

select floor(06.85) + cast(((06.85 - floor(06.85))*100) as int) / 60 + cast((cast((06.85 - floor(06.85)) * 100 as int) % 60) as float) / 100
select floor(06.60) + cast(((06.60 - floor(06.60))*100) as int) / 60 + cast((cast((06.60 - floor(06.60)) * 100 as int) % 60) as float) / 100

Related

Left-filling a text field with zeros

I have a postgres database that I can access with PGAdmin III. I run a script to change a number stored in a text field and then add left zeros to file it to four characters. It's a time field that must be stored as text. I'd like to do it in a single run instead of two. Here's the first clause to add hours to the time field as text;
UPDATE timetable
SET eta = (
CASE
WHEN (trips.starttime::int / 100) + (destination.zuluoffset * -1 ) < 24 THEN ((trips.starttime::int / 100) + (destination.zuluoffset * -1 )) * 100
WHEN (trips.starttime::int / 100) + (destination.zuluoffset * -1 ) > 23 THEN ((trips.starttime::int / 100) + (destination.zuluoffset * -1 ) - 24) * 100
END )
FROM
destination,
trips
WHERE
timetable.tripsid = trips.id;
This does fine and adds the desired number of hours while correcting for results of greater than 24 hours. However, this leave any times less than 1000 hours as three digits or even a single 0 for midnight. The field needs to be 4 characters.
So I run this as a second clause;
UPDATE timetable
SET eta = lpad(eta, 4, '0');
and this works also. But how can I add the lpad to the first Update clause? I tried putting the entire CASE statement in the lpad statement in place of eta like this;
SET eta = lpad((CASE statement here), 4, '0')
but I get this error;
ERROR: function lpad(numeric, integer, unknown) does not exist
LINE 3: SET eta = lpad((
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
I've tried casting eta with ::int, ::text, and ::varchar, but that just return a sytax error.
should be LPAD(your_col::text, 4, '0')
UPDATE timetable
SET eta = LPAD ((
CASE
WHEN (trips.starttime::int / 100) + (destination.zuluoffset * -1 ) < 24 THEN ((trips.starttime::int / 100) + (destination.zuluoffset * -1 )) * 100
WHEN (trips.starttime::int / 100) + (destination.zuluoffset * -1 ) > 23 THEN ((trips.starttime::int / 100) + (destination.zuluoffset * -1 ) - 24) * 100
END )::text, 4,'0')
FROM destination
INNER JOIN trips ON timetable.tripsid = trips.id;
Why are you using LPAD if the result of your CASE statement is numeric , use simply to_char :
UPDATE timetable
SET eta = to_char (
CASE
WHEN (trips.starttime::int / 100) + (destination.zuluoffset * -1 ) < 24 THEN ((trips.starttime::int / 100) + (destination.zuluoffset * -1 )) * 100
WHEN (trips.starttime::int / 100) + (destination.zuluoffset * -1 ) > 23 THEN ((trips.starttime::int / 100) + (destination.zuluoffset * -1 ) - 24) * 100
END , 'FM0000')
FROM destination
INNER JOIN trips ON timetable.tripsid = trips.id;

Dateadd without using function

We keep our dates in the DWH in int format.
I would like to do some simple Dateadd calculations (adding and subtract months from a date) without having to convert to date and convert back to int.
I have been able to reach something closing to working using 2 methods:
1. Using Modulo and Absolute functions:
DECLARE #EffectiveDate INT = 20121003,
#Diff INT = -12
SELECT #EffectiveDate + ( Abs(#Diff) / #diff ) * ( Abs(#Diff) + mnt ) / 12 *
10000 + (
Abs(#Diff) / #diff ) * ( ( Abs(#Diff) + mnt - 1 )%12 - mnt + 1 ) *
100
FROM (SELECT #EffectiveDate / 100%100 Mnt)T
2.By calculating the year in months, adding/subtracting the required months and dividing by 12:
DECLARE #EffectiveDate INT = 20121003,
#Diff INT = -12
SELECT ( yr * 12 + mnt + #Diff ) / 12 * 10000 +
( yr * 12 + mnt + #Diff )%12 * 100 + 1
FROM (SELECT #EffectiveDate / 100%100 Mnt,
#EffectiveDate / 10000 Yr)T
In both cases I come up with the same problem, December is represented incorrectly as 0 and effects the year outcome as well.
Any ideas?
Your logic is wrong:
SELECT ( yr * 12 + mnt + #Diff - 1) / 12 * 10000 +
(( yr * 12 + mnt + #Diff - 1) % 12 + 1) * 100 + 1
FROM (SELECT #EffectiveDate / 100%100 Mnt,
#EffectiveDate / 10000 Yr)T
Of course everything would be much easier if your store dates in DATEs :)

Convert Decimal values(hours) to Appropriate Hours in sql server 2008

I have a column called TimeSpent of type Float.
It contains values (i.e. 2.50, 1.25, 3.75, 5.60 )
I need to convert these hour values to appropriate hour values like (2:30, 1:15, 3:45 ,5:36) etc)
How can this be done?
Try this Query
select
time_decimal
,cast(cast(cast(time_decimal as int) as varchar)+
':'+cast(cast((time_decimal - cast(time_decimal as int)) * 60 as int) as varchar)+
':'+cast(cast(((time_decimal - cast(time_decimal as int)) * 60-
cast((time_decimal - cast(time_decimal as int)) * 60 as int)) * 60 as int) as varchar) as time) as real_time
from time1
SQL FIDDLE
Just do the math: the hour you can get by casting to int, for example. To get the minutes, multiply the decimal part by 60, etc.
A quick and dirty way to do it in a single query could be:
declare #d float
set #d = 1.54
select cast(#d as int) h,
cast((#d - cast(#d as int)) * 60 as int) m,
cast(((#d - cast(#d as int)) * 60
- cast((#d - cast(#d as int)) * 60 as int)) * 60 as int) s
Assuming you have created already a column with datatype time, you update your table by concatenating the left of TimeSpent till the dot and the part right of the dot multiplied by 60.
SQL Server 2012:
UPDATE yourTable SET
newTimeColumn = CONCAT(CAST(TimeSpentFloat AS INT), ':', (TimeSpentFloat - CAST(TimeSpentFloat AS INT)) * 60);
SQL Server 2008 and lower:
SELECT
CAST(CAST(2.75 AS INT) AS CHAR) + ':' + CAST((2.75 - CAST(2.75 AS INT)) * 60 AS CHAR);
See it working in an sqlfiddle.

SQL: float number to hours format

Is there a easy way to format a float number in hours in Ms SQL server 2008?
Examples:
1.5 -> 01:30
9.8 -> 09:48
35.25 -> 35:15
Thanks a lot.
I like this question!
DECLARE #input float = 1.5;
DECLARE #hour int = FLOOR(#input);
DECLARE #minutes int = (SELECT (#input - FLOOR(#input)) * 60);
SELECT RIGHT('00' + CONVERT(varchar(2), #hour), 2) + ':' + RIGHT('00' + CONVERT(varchar(2), #minutes), 2);
SELECT SUBSTRING(CONVERT(NVARCHAR, DATEADD(MINUTE, 1.5*60, ''), 108), 1, 5)
This works by:
starting from the "zero" date
adding 1.5 x 60 minutes (i.e. 1.5 hours)
formatting the result as a time, hh:mm:ss (i.e. format "108")
trimming off the seconds part
It is necessary to use 1.5 x 60 minutes instead of 1.5 hours as the DATEADD function truncates the offset to the nearest integer. If you want high-resolution offsets, you can use SECOND instead, suitable scaled (e.g. hours * 60 * 60).
Sure. Easy, but not exactly...straightforward:
declare #hours float
set #hours = -9.8
select substring('- ',2+convert(int,sign(#hours)),1) -- sign
+ right('00' + convert(varchar, floor(abs(#hours))) , 2 ) -- hours component
+ ':' -- delimiter
+ right('00' + convert(varchar,round( 60*(abs(#hours)-floor(abs(#hours))) , 0 ) ) , 2 ) -- minutes
Another option that will give the correct result. You might need to tweak it to round minutes and to ensure that both fields are 2 digits wide.
declare #hours float
set #hours = -9.8
select convert(varchar, datediff(minute,dateadd(minute,#hours*60,convert(datetime,'')),'') / 60 )
+ ':' + convert(varchar, datediff(minute,dateadd(minute,#hours*60,convert(datetime,'')),'') % 60 )
WITH m AS
SELECT Minutes = CAST(#hours * 60 AS int)
)
SELECT CAST(Minutes / 60 AS varchar) + ':' + RIGHT(100 + Minutes % 60, 2)
FROM m
select dateadd(MINUTE, cast((8.18 % 1) * 60 as int), dateadd(hour, cast(8.18 as int), convert(varchar(10), getdate(), 10)))

Convert Military time to string representation

I have an column declared as int (called HourMil) which stores the time in military format. I need to convert this values to an formatted string (HH:MM)
example
HourMil = 710 -> must be 07:10
HourMil = 1305 -> must be 13:05
Actually I am using this code (and works ok) for convert the column HourMil to the string representation.
SELECT SUBSTRING(LEFT('0',4-LEN(CAST(HourMil AS VARCHAR)))+CAST(HourMil AS VARCHAR),1,2)+':'+SUBSTRING(LEFT('0',4-LEN(CAST(HourMil AS VARCHAR)))+CAST(HourMil AS VARCHAR),3,2) FROM MYTABLE
but I think this code can be improved.
By creating a date, then formatting it:
SELECT SUBSTRING(CONVERT(nvarchar, DATEADD
(hh, HourMil / 100, DATEADD(mi, HourMil % 100, '1900-01-01')), 8), 0, 6)
Equations:
H = HourMil / 100;
M = HourMil - ( HourMil / 100 ) * 100;
Examples of working:
H = 710 / 100 = 7
M = 710 - (710 / 100) * 100 = 10
H = 1305 / 100 = 13
M = 1305 - (1305 / 100) * 100 = 5
Note: All /* operators MUST working under decimal numbers only. (integers)
Then you SQL will be:
CONCAT(CAST(H AS VARCHAR(8)), ':', CAST(M AS VARCHAR(8)));
With equations final seems to be:
CONCAT(CAST((HourMil / 100) AS VARCHAR(8)), ':', CAST((HourMil - ( HourMil / 100 ) * 100) AS VARCHAR(8)));
This is another method and also a shortest one
select stuff(right('0'+ltrim(hourmail),4),3,0,':') from
(
select 710 as hourmail union all
select 1305
) as t