SUM time values MySQL [duplicate] - mysql

This question already has answers here:
Surpassing MySQL's TIME value limit of 838:59:59
(7 answers)
Closed 4 years ago.
I am trying to sum time values and have it in the format of hours:minutes:seconds i.e. 100:30:10.
SEC_TO_TIME(SUM(TIME_TO_SEC(ActualHours))) AS Hours
But I'm having a problem because time's max value is 838:59:59.
So if summing the time is over this value it won't show i.e. if it equals 900 hours it will show as 838:59:59 which is wrong.
How do I the display the total hours if it is over 838:59:59?

If I had to do this conversion in SQL, I would do something like this:
SELECT CONCAT( ( _secs_ DIV 3600)
, ':'
, RIGHT(CONCAT('0',( _secs_ DIV 60 ) MOD 60 ),2)
, ':'
, RIGHT(CONCAT('0',( _secs_ MOD 60)),2)
) AS `h:mm:ss`
We can just replace the _secs_ with the expression that returns the number of seconds we want to convert. Using the expression given in the question, we get something like this:
SELECT CONCAT( ( SUM(TIME_TO_SEC(ActualHours)) DIV 3600)
, ':'
, RIGHT(CONCAT('0',( SUM(TIME_TO_SEC(ActualHours)) DIV 60 ) MOD 60 ),2)
, ':'
, RIGHT(CONCAT('0',( SUM(TIME_TO_SEC(ActualHours)) MOD 60)),2)
) AS `h:mm:ss`
DEMONSTRATION
The syntax provided in this answer is valid in MySQL 5.6. As a demonstration, using a user-defined variable #_secs as the expression number of seconds:
Set user-defined variable for demonstration:
SELECT #_secs_ := ( 987 * 3600 ) + ( 5 * 60 ) + 7 ;
returns
#_secs := ( 987 * 3600 ) + ( 5 * 60 ) + 7
-----------------------------------------
3553507
demonstrating the query pattern:
SELECT CONCAT( ( #_secs_ DIV 3600)
, ':'
, RIGHT(CONCAT('0',( #_secs_ DIV 60 ) MOD 60 ),2)
, ':'
, RIGHT(CONCAT('0',( #_secs_ MOD 60)),2)
) AS `hhh:mm:ss`
returns
hhh:mm:ss
---------
987:05:07

Here is one way we can do this:
SELECT
CONCAT(CAST(FLOOR(seconds / 3600) AS CHAR(50)), ':',
CAST(FLOOR(60*((seconds / 3600) - FLOOR(seconds / 3600))) AS CHAR(50)), ':',
CAST(seconds % 60 AS CHAR(50))) AS time
FROM yourTable;
For an input of 10,000,000 (ten million) seconds, this would generate:
2777:46:40
Demo

Use some simple math to concat a time period from seconds,replace 35000 with your column.
SELECT CONCAT(FLOOR(35000/3600),':',FLOOR((35000%3600)/60),':',(35000%3600)%60)
A fiddle to play with

Related

Convert integer to date DDMMYYYY

I am uploading an excel data sheet. In the sheet I have a numeric column which I want to convert to date. So 40955 should look like 04.09.1955 (DDMMYYYY)
Can someone help me out here. I tried using Data Conversion transformation component and its showing me error.
PP
Main obstacle here is that your values are not in an easy to use format.
To do what you specify it needs to break up the value into its parts, concatenate again and then convert. All this can be done in a single statement. For explanation I show the steps below.
DECLARE
#someval int = 40955,
#dateval int,
#dated date
;
SELECT
-- single extraction steps
#someval % 100 AS yearval,
( #someval / 100 ) % 100 AS monthval,
( #someval / 10000 ) AS dayval
;
SELECT
--#dateval =
-- extract year and push it to front
( #someval % 100 ) * 10000
-- extract month and push into middle
+ ( #someval / 100 ) % 100 * 100
-- extract day and keep at end
+ ( #someval / 10000 )
;
SELECT
-- clip all elements into single integer
#dateval =
( #someval % 100 ) * 10000
+ ( #someval / 100 ) % 100 * 100
+ ( #someval / 10000 )
;
SELECT
-- 112 = yyyymmdd format
#dated = CONVERT( date, CAST( #dateval AS varchar(8) ), 112 )
;
SELECT
-- show as standard (format 120) date aka ISO 8601 readable
#dated AS Dated
;
However I suspect that the value you receive from Excel is kind of Julian date. In this case the following answer will provide a solution:
convert Excel Date Serial Number to Regular Date
Keep in mind that in SSIS you need to wrap this coding into either a column or a transformation.

Invalid GIS data provided to function st_geometryfromtext in MBRContains LineFromText

We have areas table with column named 'position' that stores lattitude and longitude of that area. The column 'position' here is of 'POINT' mysql type.
I read instructions from here and followed the same but I am getting error on following query:
SELECT *
FROM areas
WHERE MBRContains(LineFromText(CONCAT(
'('
, 72.836898 + 10 / ( 111.1 / cos(RADIANS(72.836898)))
, ' '
, 18.935255 + 10 / 111.1
, ','
, 72.836898 - 10 / ( 111.1 / cos(RADIANS(18.935255)))
, ' '
, 18.935255 - 10 / 111.1
, ')' ))
,position);
I am getting Error code: 3037. Invalid GIS data provided to function st_geometryfromtext.
For your MySQL version you need to use this:
SELECT *
FROM areas
WHERE MBRContains
(
LineString
(
Point (
18.935255 + 10 / ( 111.320 / COS(RADIANS(72.836898))),
72.836898 + 10 / 111.133
),
Point (
18.935255 - 10 / ( 111.320 / COS(RADIANS(72.836898))),
72.836898 - 10 / 111.133
)
),
,position);

How to convert number of minutes to hh:mm format in SQL? [duplicate]

This question already has answers here:
mysql minutes to hours and minutes
(5 answers)
Closed 6 years ago.
I have a select query that has DURATION column to calculate number of Minutes . I want to convert those minutes to hh:mm format.
Duration has values like 0, 120, 2402165
For example:
NULL becomes 00:00
0 becomes 00:00
60 becomes 01:00
2402165 becomes 40036:05
I have already tried using different queries, but with undesirable results:
SELECT CAST(60/60 AS VARCHAR(10)) + ':' + RIGHT('0' + CAST(60%60 AS VARCHAR(2)),2)
SELECT CONVERT(VARCHAR(12),DATEADD(MINUTE,2402165,0),114)
DECLARE #minute int
SET #minute=2402165
SELECT CASE WHEN SIGN(#minute) = -1.0 THEN '-' ELSE '' END + CONVERT(varchar(10),ABS(#minute)/60) + ':' + CONVERT(varchar(10),ABS(#minute)%60)

Cumulative DATEDIFF [duplicate]

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

SQL Server - single Inline Query - (decimal remainder of x/y (rounded to 6 characters) ) / z

Can I ask for help on a SQL Statement please, I have to do the calculation inline and cannot declare variables for it
Calculation:
-91000000 / 2700000 = -33.7037037037
I need the remainder (7037037037 - but only up to 6 characters ) to be multiplied by 15000
703703 / 15000 = Final Answer of 49.913533
I thought I could do this:
select cast(ParseName(abs(cast(-91000000 as decimal)/ 2700000 ) %1,1) as numeric(8,8)) / 15000
WITH cte AS
(
SELECT -91000000 AS x, 2700000 AS y
)
SELECT ABS(ROUND((CAST(x AS decimal) / CAST(y AS decimal)) - (x/y), 6)) * 1000000 / 15000 FROM CTE