Convert four Digit number into hour format SQL - sql

I have looked into Cast and Convert, but I cannot find a way to do this. I need to convert four digits into an hour format. For instance, 0800 would become 8:00 or 1530 would become 15:30. I cannot use functions, I'm using a InterSystem's CacheSQL. Any suggestions? Thanks in advance!
EDIT:
If it is any more convenient, I can just divide the four digits by one hundred to get values like 15 from original 1500, or 8.30 from 0830. Does this make converting to hour:minute format easier?

For CacheSQL, you can do this:
SELECT {fn TRIM(LEADING '0' FROM LEFT(col_name, 2) || ':' || RIGHT(col_name, 2)) }
FROM table_name

In SQL Server 2008, given data that looks like
create table #data
(
HHMM int not null ,
)
insert #data values ( 0800 )
insert #data values ( 0815 )
insert #data values ( 1037 )
insert #data values ( 2359 )
You can say:
select * ,
strTime = right( '0' + convert(varchar, HHMM / 100 ) , 2 )
+ ':'
+ right( '0' + convert(varchar, HHMM % 100 ) , 2 ) ,
myTime = convert(time ,
right( '0' + convert(varchar, HHMM / 100 ) , 2 )
+ ':'
+ right( '0' + convert(varchar, HHMM % 100 ) , 2 ) ,
120
)
from #data
Other SQL implementations likely have similar functionality.
In earlier versions of SQL Server that lack the time datatype, just use datetime, thus:
select * ,
strTime = right( '0' + convert(varchar, HHMM / 100 ) , 2 )
+ ':'
+ right( '0' + convert(varchar, HHMM % 100 ) , 2 ) ,
myTime = convert(datetime,
right( '0' + convert(varchar, HHMM / 100 ) , 2 )
+ ':'
+ right( '0' + convert(varchar, HHMM % 100 ) , 2 ) ,
120
)
from #data
You'll get a datetime value that is 1 Jan 1900 with the desired time-of-day.

Well, if it is something like Oracle you might have a try with the to_date() function.
Read more here.
Example:
SELECT to_date(yourColumn, 'HH24MI') FROM ...
EDIT (why? see comments): If necessary (I'm actually not familiar with Oracle) you can wrap another function like TIME() around it.
SELECT TIME(to_date(yourColumn, 'HH24MI')) FROM ...
Read more about TIME() here.
</EDIT>
In MySQL the equivalent would be the STR_TO_DATE() function:
SELECT STR_TO_DATE(yourColumn, '%H%i') FROM ...
Read about STR_TO_DATE() and its parameters under the DATE_FORMAT() function.

left( case when (EndTime / 100) < 10 then ('0'+ convert(varchar, EndTime / 100 )) else convert(varchar, EndTime / 100 ) end, 2 )
+ ':'
+ right( '0' + convert(varchar, EndTime % 100 ) , 2 )

Related

How to calculate the sum of time with SQL SERVER? [duplicate]

I have a column called "WrkHrs" and the data type is time(hh:mm:ss). I want to sum up the working hours for employees. But since it's time data type sql server doesn't let me use like sum(columnname).
How can I sum up the time data type fieled in sql query?
SELECT EmployeeID, minutes_worked = SUM(DATEDIFF(MINUTE, '0:00:00', WrkHrs))
FROM dbo.table
-- WHERE ...
GROUP BY EmployeeID;
You can format it pretty on the front end. Or in T-SQL:
;WITH w(e, mw) AS
(
SELECT EmployeeID, SUM(DATEDIFF(MINUTE, '0:00:00', WrkHrs))
FROM dbo.table
-- WHERE ...
GROUP BY EmployeeID
)
SELECT EmployeeID = e,
WrkHrs = RTRIM(mw/60) + ':' + RIGHT('0' + RTRIM(mw%60),2)
FROM w;
However, you're using the wrong data type. TIME is used to indicate a point in time, not an interval or duration. Wouldn't it make sense to store their work hours in two distinct columns, StartTime and EndTime?
In order to sum up the working hours for an employee you can calculate the difference between the shift start time and end time in minutes and convert it to readable format as following:
DECLARE #StartTime datetime = '08:00'
DECLARE #EndTime datetime = '10:47'
DECLARE #durMinutes int
DECLARE #duration nvarchar(5)
SET #durMinutes = DATEDIFF(MINUTE, #StartTime, #EndTime)
SET #duration =
(SELECT RIGHT('00' + CAST((#durMinutes / 60) AS VARCHAR(2)),2) + ':' +
RIGHT('00' + CAST((#durMinutes % 60) AS VARCHAR(2)), 2))
SELECT #duration
The result : 02:47
two hours and 47 minutes
select DATEDIFF(MINUTE, '0:00:00', '00:02:08')
results in :- 2
select DATEDIFF(SECOND, '0:00:00', '00:02:08')
results in :- 128
Using seconds gives a better answer.
So I think the answer can be
SELECT
EmployeeId
, seconds_worked = SUM (DATEDIFF (SECOND, '0:00:00', WrkHrs))
FROM
tbl_employee
GROUP BY
EmployeeId;
DECLARE #Tab TABLE
(
data CHAR(5)
)
INSERT #Tab
SELECT '25:30' UNION ALL
SELECT '31:45' UNION ALL
SELECT '16:00'
SELECT STUFF(CONVERT(CHAR(8), DATEADD(SECOND, theHours + theMinutes,
'19000101'), 8), 1, 2, CAST((theHours + theMinutes) / 3600 AS VARCHAR(12)))
FROM (
SELECT ABS(SUM(CASE CHARINDEX(':', data) WHEN 0 THEN 0 ELSE 3600 *
LEFT(data, CHARINDEX(':', data) - 1) END)) AS theHours,
ABS(SUM(CASE CHARINDEX(':', data) WHEN 0 THEN 0 ELSE 60 *
SUBSTRING(data, CHARINDEX(':', data) + 1, 2) END)) AS theMinutes
FROM #Tab
) AS d
For MS SQL Server, when your WorkingTime is stored as a time, or a varchar in order to sum it up you should consider that:
1) Time format is not supporting sum, so you need to parse it
2) 23:59:59.9999999 is the maximum value for the time.
So, the code that will work to get you the total number of WorkingHours:WorkingMinutes:WorkingSeconds would be the following:
SELECT
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) / 3600),'00') as varchar(max)) + ':' +
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) % 3600 / 60),'00') as varchar(max)) + ':' +
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) % 3600 % 60),'00') as varchar(max)) as WorkingTimeSum
FROM TableName
It must be as simple as that.
Steps
convert time to seconds
sum the RESULT
convert the sum to time
Eg:
take a case you might want to sum the following time:
| present_hours |
|-----------------|
| 00:01:20.000000 |
|-----------------|
| 00:01:13.000000 |
|-----------------|
| 00:01:45.000000 |
|-----------------|
| 00:01:03.000000 |
|-----------------|
| 00:01:10.000000 |
|-----------------|
| 00:00:56.000000 |
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(present_hours))) as total_present_hours FROM time_booking;

SQL conversion from varchar to datetime

One of the columns of my SQL Server table is mm:ss of varchar type where mm = minutes and ss = seconds.
I need to get the average of that column.
Should I convert that column to datetime format first? If so can you tell me how? If not can you tell me what I should do?
Here is my failed attempt to convert it to datetime :
SELECT CONVERT(DATETIME, '2014-01-01 '+Pace+':00', 108)
Where pace is a varchar like 23:05
If you want the average, I would convert the column to number of seconds and work with that:
select avg(pace_secs) as average_in_seconds
from (select cast(left(pace, 2) as int) * 60 + cast(right(pace, 2) as int) as pace_secs
from t
) t;
If you want this back in the format, then you can do:
select right('00' + cast(avg(pace_secs) / 60 as int), 2) + ':' +
right('00' + avg(page_secs) % 60), 2)
from (select cast(left(pace, 2) as int) * 60 + cast(right(pace, 2) as int) as pace_secs
from t
) t;
declare #pace varchar(20) = '23:05 ';
SELECT cast( '2014-01-01 '+cast(#pace as varchar(5))+':00' as datetime)
For SQL2012 and later
SELECT
FORMAT(DATEADD(second,AVG(DATEDIFF(second,0,'00:'+[Pace])),0),'mm:ss')
FROM MyTable

CAST Correct VARCHAR to DateTime

Good Day
I am working of a existing SQL Server Database. What the developers did is to keep the Date and time separate. The Date is in DateTime format (what I want) but the time is incorrect. if it is 14:30 it shows as 1430 when its 09:25 shows as 925. I am trying tyo combine the date and time to have a Date Time view for an program I am writing on top of this database.
I have created the date as a normal date like this:
CASE
WHEN LEN(T0.BeginTime) = 3 THEN '0' + LEFT(T0.BeginTime, 1) + ':' + RIGHT(T0.BeginTime, 2)
ELSE LEFT(T0.BeginTime, 2) + ':' + RIGHT(T0.BeginTime, 2)
END AS 'NEW Start Time'`
The date now looks like it's the correct format but when I want to combine the date and time I get VARCHAR to DateTime error.
How can I fix this?
This is the error:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value (ONLY RAN 804 RECORDS)
Thanks
This should do the trick, Hope it helps.
DECLARE #DateTime TABLE (
DateWithTime DATE,
BeginTime INT);
INSERT INTO #DateTime
VALUES ('2014-08-04', '1525'),
('2014-08-04', '525'),
('2014-08-04', '15'),
('2014-08-04', '5'),
('2014-08-04', '0'),
('2014-08-04', '90')
;WITH cte_BeginTimeFix
AS (
SELECT
CONVERT(VARCHAR(10), DateWithTime, 120) AS DateWithTime,
RIGHT('0000' + CAST(BeginTime AS VARCHAR(4)), 4) AS BeginTime
FROM #DateTime
)
, cte_DateString
AS (
SELECT DateWithTime,
BeginTime,
DateWithTime + ' ' + STUFF(STUFF('00:00:00.000', 4, 2, RIGHT(BeginTime, 2)), 1, 2, LEFT(BeginTime, 2)) AS DateTimeStr
FROM cte_BeginTimeFix
)
SELECT DateWithTime,
BeginTime,
CASE
WHEN ISDATE(DateTimeStr) = 1 THEN CAST(DateTimeStr AS DATETIME)
ELSE NULL
END AS DateTimeStr
FROM cte_DateString
A different approach is to convert the time column in minutes and add it to the date
DATEADD(minute, T0.BeginTime / 100 * 60 + T0.BeginTime % 100
, CONVERT(VARCHAR, T0.BeginDate, 112))
with that the length of the time column doesn't matter
This should work:
CONVERT
(
DATETIME,
CONVERT(VARCHAR,T0.Date,112) +
' ' +
CASE
WHEN ISNULL(T0.BeginTime,'0') = '0'
THEN '00:00'
ELSE
RIGHT
(
'00' + LEFT(T0.BeginTime,LEN(T0.BeginTime) - 3),
2
) +
':' +
RIGHT(T0.BeginTime,2)
END
)

How to sum up time field in SQL Server

I have a column called "WrkHrs" and the data type is time(hh:mm:ss). I want to sum up the working hours for employees. But since it's time data type sql server doesn't let me use like sum(columnname).
How can I sum up the time data type fieled in sql query?
SELECT EmployeeID, minutes_worked = SUM(DATEDIFF(MINUTE, '0:00:00', WrkHrs))
FROM dbo.table
-- WHERE ...
GROUP BY EmployeeID;
You can format it pretty on the front end. Or in T-SQL:
;WITH w(e, mw) AS
(
SELECT EmployeeID, SUM(DATEDIFF(MINUTE, '0:00:00', WrkHrs))
FROM dbo.table
-- WHERE ...
GROUP BY EmployeeID
)
SELECT EmployeeID = e,
WrkHrs = RTRIM(mw/60) + ':' + RIGHT('0' + RTRIM(mw%60),2)
FROM w;
However, you're using the wrong data type. TIME is used to indicate a point in time, not an interval or duration. Wouldn't it make sense to store their work hours in two distinct columns, StartTime and EndTime?
In order to sum up the working hours for an employee you can calculate the difference between the shift start time and end time in minutes and convert it to readable format as following:
DECLARE #StartTime datetime = '08:00'
DECLARE #EndTime datetime = '10:47'
DECLARE #durMinutes int
DECLARE #duration nvarchar(5)
SET #durMinutes = DATEDIFF(MINUTE, #StartTime, #EndTime)
SET #duration =
(SELECT RIGHT('00' + CAST((#durMinutes / 60) AS VARCHAR(2)),2) + ':' +
RIGHT('00' + CAST((#durMinutes % 60) AS VARCHAR(2)), 2))
SELECT #duration
The result : 02:47
two hours and 47 minutes
select DATEDIFF(MINUTE, '0:00:00', '00:02:08')
results in :- 2
select DATEDIFF(SECOND, '0:00:00', '00:02:08')
results in :- 128
Using seconds gives a better answer.
So I think the answer can be
SELECT
EmployeeId
, seconds_worked = SUM (DATEDIFF (SECOND, '0:00:00', WrkHrs))
FROM
tbl_employee
GROUP BY
EmployeeId;
DECLARE #Tab TABLE
(
data CHAR(5)
)
INSERT #Tab
SELECT '25:30' UNION ALL
SELECT '31:45' UNION ALL
SELECT '16:00'
SELECT STUFF(CONVERT(CHAR(8), DATEADD(SECOND, theHours + theMinutes,
'19000101'), 8), 1, 2, CAST((theHours + theMinutes) / 3600 AS VARCHAR(12)))
FROM (
SELECT ABS(SUM(CASE CHARINDEX(':', data) WHEN 0 THEN 0 ELSE 3600 *
LEFT(data, CHARINDEX(':', data) - 1) END)) AS theHours,
ABS(SUM(CASE CHARINDEX(':', data) WHEN 0 THEN 0 ELSE 60 *
SUBSTRING(data, CHARINDEX(':', data) + 1, 2) END)) AS theMinutes
FROM #Tab
) AS d
For MS SQL Server, when your WorkingTime is stored as a time, or a varchar in order to sum it up you should consider that:
1) Time format is not supporting sum, so you need to parse it
2) 23:59:59.9999999 is the maximum value for the time.
So, the code that will work to get you the total number of WorkingHours:WorkingMinutes:WorkingSeconds would be the following:
SELECT
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) / 3600),'00') as varchar(max)) + ':' +
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) % 3600 / 60),'00') as varchar(max)) + ':' +
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) % 3600 % 60),'00') as varchar(max)) as WorkingTimeSum
FROM TableName
It must be as simple as that.
Steps
convert time to seconds
sum the RESULT
convert the sum to time
Eg:
take a case you might want to sum the following time:
| present_hours |
|-----------------|
| 00:01:20.000000 |
|-----------------|
| 00:01:13.000000 |
|-----------------|
| 00:01:45.000000 |
|-----------------|
| 00:01:03.000000 |
|-----------------|
| 00:01:10.000000 |
|-----------------|
| 00:00:56.000000 |
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(present_hours))) as total_present_hours FROM time_booking;

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)))