Convert hours,minutes to days,hours,minutes - sql

I have a Query that shows downtime in hours, minutes but would need it to show it in Days,hours,minutes and maybe Another version that shows Days,hours
I'm not good at coding, sorry.
${SQL: SELECT CAST( CAST(('${N=Alerting;M=Downtime}') AS int) / 60 AS varchar) + ' hours ' + right('0' + CAST(CAST(('${N=Alerting;M=Downtime}') AS int) % 60 AS varchar(2)),2) + ' minutes'}

${SQL: SELECT CAST( CAST(('${N=Alerting;M=Downtime}') AS int) / 1440 AS varchar) + ' days ' + right('0' + CAST(CAST(('${N=Alerting;M=Downtime}') AS int) % 1440 / 60 AS varchar(2)),2) + ' hours ' + right('0' + CAST(CAST(('${N=Alerting;M=Downtime}') AS int) % 60 AS varchar(2)),2) + ' minutes'}

Related

SQL Server : conversion failed when converting date and/or time from character with string past 12pm

For the past few days my code has worked, but today it has the following error:
Conversion failed when converting date and/or time from character string
Here is my code:
DECLARE #run_time INT
DECLARE #run_duration INT
SET #run_time = '120609'
SET #run_duration = '2600'
SELECT
h.step_id,
CAST(j.[name] AS VARCHAR) as JobName,
h.step_name,
CAST(REPLACE(LEFT(CAST(case
when len(#run_time) = 1 then '00:00:0' + cast(#run_time as varchar)
when len(#run_time) = 2 then '00:00:' + cast(#run_time as varchar)
when len(#run_time) = 3 then '00:0' + cast(left(#run_time,1) as varchar) + ':' + cast(right(#run_time,2) as varchar)
when len(#run_time) = 4 then '00:' + cast(left(#run_time,2) as varchar) + ':' + cast(right(#run_time,2) as varchar)
when len(#run_time) = 5 then '0' + cast(left(#run_time,1) as varchar) + ':' + SUBSTRING(CAST(#run_time AS VARCHAR), 2, 2) + ':' + SUBSTRING(CAST(#run_time AS VARCHAR), 4,2)
when len(#run_time) = 6 then cast(left(#run_time,2) as varchar) + ':' + SUBSTRING(CAST(#run_time AS VARCHAR), 2,2) + ':' + SUBSTRING(CAST(#run_time AS VARCHAR), 4,2)
END AS TIME), 8), ':', '') AS INT) StartTime
I discovered the only time the error appears is when the run_time goes past 120000 (12pm), hence why I've never noticed it before because the agent jobs have ran at 3am. It shouldn't be an issue in the future, but just in case it is I would like a fix for this. I can't find an example anywhere that's similar to my code. Unfortunately casting the results like this is the only way I can get a graph in SSRS to work. (INT > VARCHAR > TIME > INT).
edit - here is a better example of my code using one of the proposed answers:
SELECT
h.step_id,
CAST(j.[name] AS VARCHAR) as JobName,
h.step_name,
CAST(stuff(stuff(right('0000000' + h.run_time, 6), 5, 0, ':'), 3, 0, ':') as time)
FROM
msdb.dbo.sysjobs j
INNER JOIN msdb.dbo.sysjobhistory h ON j.job_id = h.job_id
Thanks,
If you are trying to calculate the start time from a string in HHMMSS format, then this method seems much simpler to me:
select cast(stuff(stuff(right('0000000' + str, 6), 5, 0, ':'), 3, 0, ':') as time)
from (values ('120609'), ('0'), ('1001')) v(str)
In your case the problem is the string which you are trying to convert: "12:20:60"
The converstion to TIME type fails.
DECLARE #run_time INT
DECLARE #run_duration INT
SET #run_time = '120609'
SET #run_duration = '2600'
SELECT
-- h.step_id,
--CAST(j.[name] AS VARCHAR) as JobName,
-- h.step_name,
--CAST(REPLACE(LEFT(CAST(
case
when len(#run_time) = 1 then '00:00:0' + cast(#run_time as varchar)
when len(#run_time) = 2 then '00:00:' + cast(#run_time as varchar)
when len(#run_time) = 3 then '00:0' + cast(left(#run_time,1) as varchar) + ':' + cast(right(#run_time,2) as varchar)
when len(#run_time) = 4 then '00:' + cast(left(#run_time,2) as varchar) + ':' + cast(right(#run_time,2) as varchar)
when len(#run_time) = 5 then '0' + cast(left(#run_time,1) as varchar) + ':' + SUBSTRING(CAST(#run_time AS VARCHAR), 2,2) + ':' + SUBSTRING(CAST(#run_time AS VARCHAR), 4,2)
when len(#run_time) = 6 then cast(left(#run_time,2) as varchar) + ':' + SUBSTRING(CAST(#run_time AS VARCHAR), 2,2) + ':' + SUBSTRING(CAST(#run_time AS VARCHAR), 4,2)
END ,
SUBSTRING(CAST(#run_time AS VARCHAR), 4,2)
--AS TIME)
--,8), ':', '') AS INT) StartTime
Did you check this out?
How to convert an integer (time) to HH:MM:SS::00 in SQL Server 2008?
The best solution should be the one proposed by Gordon
This works for me:
SELECT
h.step_id,
CAST(j.[name] AS VARCHAR) as JobName,
h.step_name,
-- CAST(stuff(stuff(right('0000000' + h.run_time, 6), 5, 0, ':'), 3, 0, ':') as time)
(h.run_time / 1000000) % 100 as hour,
(h.run_time / 10000) % 100 as minute,
(h.run_time / 100) % 100 as second,
(h.run_time % 100) * 10 as millisecond,
dateadd(hour, (h.run_time / 1000000) % 100, dateadd(minute, (h.run_time / 10000) % 100, dateadd(second, (h.run_time / 100) % 100, dateadd(millisecond, (h.run_time % 100) * 10, cast('00:00:00' as time(2))))))
FROM
msdb.dbo.sysjobs j
INNER JOIN msdb.dbo.sysjobhistory h ON j.job_id = h.job_id
Btw, the CAST drives to error for me, as well
In case you don't want to use the select statement:
DECLARE #run_time INT
DECLARE #time_result TIME
SET #run_time = '120609'
SET #time_result = dateadd(hour, (#run_time / 1000000) % 100, dateadd(minute, (#run_time / 10000) % 100, dateadd(second, (#run_time / 100) % 100, dateadd(millisecond, (#run_time % 100) * 10, cast('00:00:00' as time(2))))))
select #time_result

Minutes to hh:mm format in SQL Server 2008 query

I have a column Time in my table. It holds a time value in minutes, ie: 605. What I want it to show it as 10:05, as hh:mm format.
I am doing it like this:
...
Time = cast(AVG(Time) / 60 as varchar) + ':' + cast(AVG(Time) % 60 as varchar),
...
It shows the value as 10:5, but I want to make it as 10:05 and I couldn't find out a way to add '0' before '5' in the minutes section.
Any help would be appreciated.
Try this:
SELECT
TIME = CASE WHEN #t < 600 THEN '0' ELSE '' END +
CAST(Time / 60 as varchar(10)) + ':' +RIGHT(100 +(Time % 60), 2)
Example:
DECLARE #t int = 55121
SELECT
TIME = CASE WHEN #t < 600 THEN '0' ELSE '' END +
CAST(#t / 60 as varchar(10)) + ':' +RIGHT(100 +(#t % 60), 2)
Result:
Time
918:41
You could simply add a Right('0' + ...,2) expression as below to get the '0' in there.
Time = cast(AVG(Time) / 60 as varchar) + ':' + RIGHT('0'+cast(AVG(Time) % 60 as varchar),2)
To answer your question in comments, getting DD:HH:MM is a similar setup.
DayTime = cast(AVG(Time) / 1440 as varchar) + ':' + RIGHT('0' + cast((AVG(Time) / 60) % 24 as varchar),2) + ':' + RIGHT('0'+cast(AVG(Time) % 60 as varchar),2)
You can use a case expression to do this.
Also you should always specify the length of varchar when you use cast, or it would only show the first character.
case when len(cast(AVG(Time)%60 as varchar(2))) < 2 then '0'+cast(AVG(Time)%60 as varchar(2))
else cast(AVG(Time)%60 as varchar(2))
end

Right SQL statement to get the late and OT of employees

Here is my sql query as of the moment:
select Employee_Number, Cast([DateTime] as Date) as 'DateTime', MIN([DateTime]) as 'MIN', MAX([DateTime]) as 'MAX' , [Hours Worked] =
CAST((DATEDIFF(HOUR ,min([DateTime]), max([DateTime])) / 24) AS VARCHAR) +
' Days ' +
CAST((DATEDIFF(HOUR , min([DateTime]), max([DateTime])) % 24) AS VARCHAR) +
' Hours ' +
CAST((DATEDIFF(MINUTE, min([DateTime]), max([DateTime])) % 60) AS VARCHAR) +
' Minutes ' +
CAST((DATEDIFF(SECOND, min([DateTime]), max([DateTime])) % 60) AS VARCHAR) +
' Seconds ' , [Over Time] = CAST((DATEDIFF(HOUR, '17:30:00:000', MAX([DateTime])) % 24) AS VARCHAR) + ' Hours ' +
CAST((DATEDIFF(MINUTE, '17:30:00:000', max([DateTime])) % 60) AS VARCHAR) + ' Minutes', [LATE] =
CAST((DATEDIFF(HOUR, '08:30:00:000',Min([DATETIME])) % 24) AS VARCHAR) + ' Hours ' + CAST((DATEDIFF(MINUTE, '08:30:00:000', MIN([DateTime])) % 60) AS VARCHAR) + ' Minutes'
from tblExtract group by Employee_Number, Cast([DateTime] as Date)
And this is what this query shows:
The problem arose if the employee entered early before 8:30 and if he leaves early as well before 17:30
How can I correct this? How Can I get a Case where if the Employee leaves or arrive early the LATE or Overtime Column would have a value of '0 hours 0 minutes'?
If you want to display '0 Hours 0 Minutes' if a person arrives/leaves early, you can use CASE for that.
select Employee_Number, Cast([DateTime] as Date) as 'DateTime', MIN([DateTime]) as 'MIN', MAX([DateTime]) as 'MAX' , [Hours Worked] =
CAST((DATEDIFF(HOUR ,min([DateTime]), max([DateTime])) / 24) AS VARCHAR) +
' Days ' +
CAST((DATEDIFF(HOUR , min([DateTime]), max([DateTime])) % 24) AS VARCHAR) +
' Hours ' +
CAST((DATEDIFF(MINUTE, min([DateTime]), max([DateTime])) % 60) AS VARCHAR) +
' Minutes ' +
CAST((DATEDIFF(SECOND, min([DateTime]), max([DateTime])) % 60) AS VARCHAR) +
' Seconds ' , [Over Time] = CASE WHEN DATEDIFF(MINUTE, '17:30:00:000', CONVERT(TIME, MAX([DateTime]))) < 0
THEN '0 Hours 0 Minutes'
ELSE
CAST((DATEDIFF(HOUR, '17:30:00:000', MAX([DateTime])) % 24) AS VARCHAR) + ' Hours ' +
CAST((DATEDIFF(MINUTE, '17:30:00:000', max([DateTime])) % 60) AS VARCHAR) + ' Minutes'
END,
[LATE] = CASE WHEN DATEDIFF(MINUTE, '08:30:00:000', CONVERT(TIME, MIN([DateTime]))) < 0
THEN '0 Hours 0 Minutes'
ELSE
CAST((DATEDIFF(HOUR, '08:30:00:000',Min([DATETIME])) % 24) AS VARCHAR) +
' Hours ' + CAST((DATEDIFF(MINUTE, '08:30:00:000', MIN([DateTime])) % 60) AS VARCHAR) + ' Minutes'
END
from Extraction
group by Employee_Number, Cast([DateTime] as Date)
SQL Fiddle demo

SQL server, Converting Seconds to Minutes, Hours, Days

I have a database column containing an integer value that represents a systems up time in seconds. I'd really like a query to be able to show me that up time in a easy to read format day(s) hour(s) minute(s) but I'm not quite sure how to do it. A lot of examples I've found appear to use parameters as an example but never much of how to use it in a select function.
I need the time to be the same as what's displayed on a website too. I tried one query earlier and its added days and removed minutes. Can anyone help me out?
Source data:
PDT0014 6141
PDT0008 4990
PDT0024 840227
PDT0033 2301
PDT0035 5439
PDT0005 3434
PDT0019 5482
Sample code:
SELECT tblAssets.AssetName,
(case when tblAssets.Uptime> (24*60*60)
then
cast(datepart(day,datediff(dd, 0, dateadd(second, tblAssets.Uptime, 0))) as varchar(4))
+ ' Day(s) ' + convert(varchar(2), dateadd(second, tblAssets.Uptime, 0), 108) +' Hour(s)'
else
convert(varchar(5), dateadd(second, tblAssets.Uptime, 0), 108) + ' Hour(s) Minute(s) '
end) AS Uptime
FROM tblAssets
Desired Query Output:
PDT0014 01:42 Hour(s) Minute(s)
PDT0008 01:23 Hour(s) Minute(s)
PDT0024 10 Day(s) 17 Hour(s)
PDT0033 00:38 Hour(s) Minute(s)
PDT0035 01:30 Hour(s) Minute(s)
PDT0005 00:57 Hour(s) Minute(s)
PDT0019 01:31 Hour(s) Minute(s)
Depending on the output you want:
DECLARE #s INT = 139905;
SELECT CONVERT(VARCHAR(12), #s /60/60/24) + ' Day(s), '
+ CONVERT(VARCHAR(12), #s /60/60 % 24)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), #s /60 % 60), 2)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), #s % 60), 2);
Result:
1 Day(s), 14:51:45
Or:
DECLARE #s INT = 139905;
SELECT
CONVERT(VARCHAR(12), #s /60/60/24) + ' Day(s), '
+ CONVERT(VARCHAR(12), #s /60/60 % 24) + ' Hour(s), '
+ CONVERT(VARCHAR(2), #s /60 % 60) + ' Minute(s), '
+ CONVERT(VARCHAR(2), #s % 60) + ' Second(s).';
Result:
1 Day(s), 14 Hour(s), 51 Minute(s), 45 Second(s).
You can replace 60/60/24 with 86400 etc. but I find it better self-documenting if you leave in the /seconds/minutes/hours calculations. And if you are going against a table, just use column_name in place of #s.
I tend to use:
CAST(FLOOR(seconds / 86400) AS VARCHAR(10))+'d ' +
CONVERT(VARCHAR(5), DATEADD(SECOND, Seconds, '19000101'), 8)
The top part just gets your days as an integer, the bottom uses SQL-Server's convert to convert a date into a varchar in the format HH:mm:ss after converting seconds into a date.
e.g.
SELECT Formatted = CAST(FLOOR(seconds / 86400) AS VARCHAR(10))+'d ' +
CONVERT(VARCHAR(5), DATEADD(SECOND, Seconds, '19000101'), 8),
Seconds
FROM ( SELECT TOP 10
Seconds = (ROW_NUMBER() OVER (ORDER BY Object_ID) * 40000)
FROM sys.all_Objects
ORDER BY Object_ID
) S
Example on SQL Fiddle
N.B. Change CONVERT(VARCHAR(5), DATEADD(.. to CONVERT(VARCHAR(8), DATEADD(.. to keep the seconds in the result
EDIT
If you don't want seconds and need to round to the nearest minute rather than truncate you can use:
SELECT Formatted = CAST(FLOOR(ROUND(Seconds / 60.0, 0) * 60 / 86400) AS VARCHAR(10))+'d ' +
CONVERT(VARCHAR(5), DATEADD(SECOND, ROUND(Seconds / 60.0, 0) * 60, '19000101'), 8),
Seconds
FROM ( SELECT Seconds = 3899
) S
I have just replaced each reference to the column seconds with:
ROUND(Seconds / 60.0, 0) * 60
So before doing the conversion rounding your seconds value to the nearest minute
You can convert seconds to days by dividing by 86400
You can convert seconds to hours by dividing by 3600, but you need to get the remainder
(by subtracting off the total days converted to hours)
You can convert seconds to minutes by dividing by 60, but you need to get the remainder (by subtracting off the total hours converted to minutes)
Seconds you can just report, but like minutes you want to only report the remainder of seconds (by sutracting off the total minutes converted to seconds)
SELECT FLOOR( UpTime / 86400 ) AS DAYS
, FLOOR( ( UpTime / 3600 ) - FLOOR( UpTime / 86400 ) * 24 ) AS HOURS
, FLOOR( ( UpTime / 60 ) - FLOOR( UpTime / 3600 ) * 60 ) AS MINUTES
, UpTime - FLOOR( UpTime / 60 ) * 60 AS SECONDS
FROM ( SELECT 269272 AS UpTime ) AS X
269272 represents 3 days (259200 seconds), 2 hours (7200 seconds), 47 minutes (2820 seconds) and 52 seconds.
This query produces:
| DAYS | HOURS | MINUTES | SECONDS |
------------------------------------
| 3 | 2 | 47 | 52 |
Substituting 125 (2 minutes, 5 seconds) for 259200 will produce:
| DAYS | HOURS | MINUTES | SECONDS |
------------------------------------
| 0 | 0 | 2 | 5 |
To convert this to a string representation, you can use SQL Server 2012's FORMAT function:
SELECT CASE
WHEN DAYS > 0 THEN
FORMAT( DAYS, '##' ) + ' Day(s) ' + FORMAT( HOURS, '##' ) + ' Hour(s)'
ELSE
FORMAT( HOURS, '##' ) + ':' + FORMAT( MINUTES, '##' ) + ' Hour(s) Minute(s)'
END AS UpTimeString
FROM (
SELECT FLOOR( UpTime / 86400 ) AS DAYS
, FLOOR( ( UpTime / 3600 ) - FLOOR( UpTime / 86400 ) * 24 ) AS HOURS
, FLOOR( ( UpTime / 60 ) - FLOOR( UpTime / 3600 ) * 60 ) AS MINUTES
, UpTime - FLOOR( UpTime / 60 ) * 60 AS SECONDS
FROM ( SELECT 125 AS UpTime ) AS X
) AS UptimeSubselect
This is another approach using DATEPART():
DECLARE #S INT = 86472,
#START DATETIME = CONVERT(DATETIME,0)
DECLARE #END DATETIME = DATEADD(SECOND,#S, #START)
SELECT CONVERT(VARCHAR(10),DATEPART(DAY,#END)-1) + ' Day(s) ' +
RIGHT(CONVERT(VARCHAR(10),100+DATEPART(HOUR, #END)),2) + ':' +
RIGHT(CONVERT(VARCHAR(10),100+DATEPART(MINUTE, #END)),2) + ':' +
RIGHT(CONVERT(VARCHAR(10),100+DATEPART(SECOND, #END)),2)
If you don't need to format time part:
SELECT CONVERT(VARCHAR(10),DATEPART(DAY,#END)-1) + ' Day(s) ' +
CONVERT(VARCHAR(10),DATEPART(HOUR, #END)) + ' Hour(s)' +
CONVERT(VARCHAR(10),DATEPART(MINUTE, #END)) + ' Minute(s)' +
CONVERT(VARCHAR(10),DATEPART(SECOND, #END)) + ' Second(s)'
DECLARE #Seconds INT = 86200;
SELECT CONVERT(VARCHAR(15),
CAST(CONVERT(VARCHAR(12), #Seconds / 60 / 60 % 24)
+':'+ CONVERT(VARCHAR(2), #Seconds / 60 % 60)
+':'+ CONVERT(VARCHAR(2), #Seconds % 60) AS TIME), 100) AS [HH:MM:SS (AM/PM)]

Datetime pattern for yyyy.mm.dd.hh.mm.ss pattern code?

What is the DATE FORMAT CODE for "yyyy.mm.dd.hh.mm.ss"?
I know that 34 (date format code) is "yyyymmddhhmmss", but what about the code for "yyyy.mm.dd.hh.mm.ss"?
This is on SQL 2005.
CAST and CONVERT on MSDN says "no".
You have to CONVERT twice with styles 102 and 108, with a concatenation and REPLACE.
Where did you get the "34" date format code from?
As gbn said, using one of the existing formats with some string concatenation would work. Another option is:
SELECT
CAST(YEAR(my_date) AS CHAR(4)) + '.' +
RIGHT('0' + CAST(MONTH(my_date) AS VARCHAR(2)), 2) + '.' +
RIGHT('0' + CAST(DAY(my_date) AS VARCHAR(2)), 2) + '.' +
RIGHT('0' + CAST(DATEPART(HOUR, my_date) AS VARCHAR(2)), 2) + '.' +
RIGHT('0' + CAST(DATEPART(MINUTE, my_date) AS VARCHAR(2)), 2) + '.' +
RIGHT('0' + CAST(DATEPART(SECOND, my_date) AS VARCHAR(2)), 2)
Considering
SELECT CONVERT(VARCHAR(16), GETDATE(), 120) AS [YYYY-MM-DD]
---returns--- yyyy-mm-dd hh:ss
and you can use REPLACE to convert strings
REPLACE('a b c',' ','.')
----returns--- a.b.c
and you can recursively stack things you get to this
Select (
replace((replace((replace(CONVERT(VARCHAR(16), GETDATE(), 120),' ','.')), ':', '.')), '-', '.')
)
which returns: yyyy.mm.dd.hh.ss
works great for datetime stamps or filenames!