TIme - SQL (Minutes and Seconds) - sql

I created a TIME table. This table has two columns: one for minutes and another one for seconds. I made their datatype as a Decimal.
Is there a way to create a derivative column where minutes and seconds are in this format mm:ss from my two columns?
IF NOT, How do I insert data into my minute column if its not a DECIMAL type? What type should it be?
Thank you!
Note I am using SQL server

Your comments make it sound like you're trying to do arithmetic on intervals (or durations).
SQL Server's time data type "Defines a time of a day. The time is without time zone awareness and is based on a 24-hour clock." You can't add two time values; 2 o'clock + 3 o'clock is literally nonsense. In SQL Server 2012 . . .
select cast('2:00' as time) + cast('3:00' as time)
Operand data type time is invalid for add operator.
Other dbms might return a nonsensical number.
Standard SQL includes a data type called interval, which supports the arithmetic and formatting you'd expect. So 2 o'clock + 3 hours would return 5:00:00 (5 o'clock). In the absence of support for the interval data type, store the most granular unit (seconds, for you) as an integer, and format it yourself for display. I might use a view, myself.
declare #val as integer;
-- 10:01:12, 10 hours, 1 minute, 12 seconds, in seconds.
set #val = (10 * 60 * 60) + (1 * 60) + 12;
-- Leading zeroes for minutes and seconds.
select #val as total_sec,
concat(#val / (60 * 60), ':', format((#val / 60) % 60, 'D2'), ':', format(#val % 60, 'D2')) as total_time
total_sec total_time
--
36072 10:01:12

As #mclaassen pointed out, I'd be curious why you aren't using the built in time data type.
That said, if you really want to build a time table by hand, then you can have a calculated column. Let's call it timeString.
alter table [time]
add timeString as (left('0' + cast([minutes] as varchar(10)), 2) + ':' + left('0' + cast([seconds] as varchar(10)), 2))
See https://msdn.microsoft.com/en-us/library/ms188300.aspx for documentation on calculated columns in SQL Server.

Related

How to convert an integer value to time (HH:MM:SS) in SQL Server?

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

SQL Creating a table for song duration

I am trying to create a table in SQL which is about Music, it should contain songDuration. Which means I gotta hold minutes:seconds information in the table. But i have no idea what to use for the type. I am using SQL server.
Edit: I want to use the database for an ASP.NET Core web application. I was using a ready-to-use SQL database like northwnd. Now, I am trying to create one. So, I will not see the timing with SELECT function in SQL query. So, I need to use something that makes it mm:ss otomaticly. Is there is a type that I can decleare like that?
create table musics(
songDuration type,
...)
Why just don't you use int?
So you could calculate duration in the way you like.
E.g. minutes,hours, etc.
There's a datatype time which would be the logical choice, that stores it in format HH:mm:ss with an optional amount of fractional seconds determined by the size you declare the field (e.g. time(3) holds it to three decimal places)
If your source data is already in this notation it makes it getting it in the table easy and simple sorting/filtering operates as you expect. The downside to doing this is if you want to do certain operations such as SUM or AVG (because as a_horse_with_no_name pointed out in their comment) time technically represents a point in time not a duration and you'd have to do some workaround like so:
SELECT totalduration = SUM(DATEDIFF(SECOND, '0:00:00', duration))
FROM dbo.table
Alternatively you could store the number of (say) seconds in the duration using an int, but if you don't already have the information in that format you'd have to do some (light) conversion when inserting the data, and then back if you want to display in mm:ss
e.g:
SELECT CONVERT(varchar, DATEADD(SECOND, durationinseconds, 0), 8) FROM dbo.table
which would convert it back to hh:mm:ss format.
I do this by using an int column, and store the seconds there.
In your client you can calculate from the seconds howmany days, hours, minutes and seconds it is and display it like you want.
To display it in sql you can use this for example
declare #seconds int = 350
select right('00' + convert(varchar, datepart(hour, dateadd(s, #seconds, 0)) + ((#seconds / 86400) * 24)), 2)
+ ':' + right('00' + convert(varchar, datepart(minute, dateadd(s, #seconds, 0))), 2)
+ ':' + right('00' + convert(varchar, datepart(second, dateadd(s, #seconds, 0))), 2)
this will display
00:05:50
which is 0 hours, 5 minutes and 50 seconds
IF the value of seconds is larger than a day, this will be no problem. The number of hours will simply be greater
a value of 350000 will display 97:13:20

SQL Server Converting Decimal into Time hh:mm, I need the total hours

I need to be able to get the total hours and minutes if it is over 24 hours from a decimal column in SQL Server.
This is the code I am using:
CAST(CAST(DATEADD(SECOND, 1654.86 * 60, 0) AS Time(0)) AS VARCHAR(5))
Since it's over 24 hours the output is "03:34" I would like for it to be "27:34" or if possible to tell me it will take 3 working days and "03:34" (not sure how that would work).
Thank you in advance! Paul
As explained in the comments, the time data type is not designed to represent any sort of interval or timespan, it is only designed to represent clock time. As such, it is not capable of displaying 27 hours. Instead you need to build this string yourself with methods other than simple CAST as type:
DECLARE #d table(decimal_column decimal(15,2));
INSERT #d(decimal_column) VALUES(1654.86);
SELECT d.decimal_column,
nice_time = CONVERT(varchar(11), FLOOR(h)) + ':'
+ RIGHT('0' + CONVERT(varchar(11), FLOOR(m)), 2)
FROM #d AS d
CROSS APPLY
(
VALUES(d.decimal_column/60, d.decimal_column%60)
) AS extracted(h,m);
Results:
decimal_column
nice_time
1654.86
27:34
Example db<>fiddle
You may have edge cases where you want actual rounding logic instead of FLOOR() - but if you have those cases, include them in your question so we know the desired output.
select CONVERT(VARCHAR, CONVERT(INT, 1654.86/60)) + ':'
+ CONVERT(VARCHAR, CONVERT(INT, 1654.86-(CONVERT(INT, 1654.86/60)*60)))
You can create a function for this query, it is very performance. Because we will not use the same operations in multi sections.

SQL operand data type datetime / varchar is invalid for sum operator

I am trying to subtract one column from another column, and then sum the result. However, whatever I change I keep getting one of the two errors as mentioned in the title.
From all other questions posted, I derived that my statement should be something like:
SELECT SUM(EndTime-BeginTime) AS TotalTime FROM TimeRegister
WHERE OrderNumber = 00000 AND Activity = 11111;
As per suggestion in another topic, I changed the statement to:
SELECT SUM(CONVERT(varchar(EndTime-BeginTime), 108)) AS TotalTime FROM TimeRegister
WHERE OrderNumber = 00000 AND Activity = 11111;
However, I still receive the error.
The times are stored as follows:
1-1-1900 7:30:00
Thanks for any suggestion...
Edit 1: Oh, I am using a Microsoft Query through ODBC for SQL in Excel, kind of like:
Excel vlookup incorporating SQL table
Edit 2: I prefer to have the output again in the HH:MM format.
The thing is, when I copy the complete database to excel, everything works just fine. I can subtract the columns and sum up. I just dont want to that manually every day....
I just checked the SQL database, and the column is of Date/Time type.
First of all, trying to solve date or numeric issues by converting to text never solves anything, it adds additional problems like failed conversions or unexpected results.
SQL Server doesn't have a time interval type. If you subtract two datetime values you get back another datetime value that represents the difference as the offset since 1900-01-01. The following query :
select getdate() - dateadd(d,-1,getdate())
Will return :
1900-01-02 00:00:00.000
Which is 1 full day after 1900-01-01.
datetime values can't be summed though. SQL Server does have a time type but that just represents the time of day. Even if today - yesterday worked, converting that to time would return 00:00.
A quick solution is to use DATEDIFF to calculate the difference between two dates in whatever unit is required - hourss, minutes, seconds etc. Be aware though that DATEDIFF returns the number of interval boundaries crossed. DATEDIFF(DAY,...) between 11pm yesterday and 1am today will return 1, because 1 day boundary was crossed.
You can use
SELECT sum(datediff(minute,EndTime,BeginTime)) AS TotalMinutes
FROM TimeRegister
WHERE OrderNumber = 00000 AND Activity = 11111;
To calculate the difference in minutes and format it as a time interval on the client.
Another option is to cast the datetime to a float before summing, then back to datetime:
SELECT cast( sum(cast(EndTime - BeginTime as datetime)) as datetime) AS TotalOffset
FROM TimeRegister
WHERE OrderNumber = 00000 AND Activity = 11111;
A 2-day duration would appear as :
1900-01-03 00:00:00.000
This works because datetime can be cast to a float whose integral part represents the offset from 1900-01-01 and the fractional part the time.
A client written in a language like C# that does support intervals could subtract 1900-01-01 from this to get back the actual duration, eg :
TimeSpan duration = sumResult - new DateTime(1900,1,1);
Another option would be to avoid the final cast and just use the resulting float value as the number of days.
Displaying in Excel
The last option could be the easiest way to display the duration in Excel! Excel dates are actually stored as floats. What makes them appear as dates or times is the cell's formatting.
You can set a cells format to [h]:mm:ss to display any number as a duration. The [] is important - without it Excel will only display the time part of the "date".
If you enter 2 in a cell, h:mm:ss will show it as 0:00:00 while [h]:mm:ss will display 48:00:00, 48 hours.
Despite its strangeness,
SELECT sum(cast(EndTime - BeginTime as datetime)) AS TotalDuration
FROM TimeRegister
WHERE OrderNumber = 00000 AND Activity = 11111;
May be the best option to display a duration sum in Excel
You seem to want datediff():
SELECT SUM(DATEDIFF(second, BeginTime, EndTime) AS TotalTime
FROM TimeRegister
WHERE OrderNumber = 00000 AND Activity = 11111;
How about the following:
WITH totalTime AS (
SELECT SUM(DATEDIFF(second, EndTime, BeginTime)) as TimeInSecond
FROM TimeRegister
WHERE OrderNumber = 00000 AND Activity = 11111;
)
SELECT RIGHT('0' + CAST(TimeinSecond / 3600 AS VARCHAR),2) + ':' +
RIGHT('0' + CAST((TimeinSecond / 60) % 60 AS VARCHAR),2) + ':' +
RIGHT('0' + CAST(TimeinSecond % 60 AS VARCHAR),2) AS TimeElapsed
FROM totalTime;
In this solution, the time is converted into seconds, before being totalled, and then converted to HH:MM:SS.

Converting hours into minutes in SQL

i'm trying to write a regular expression that will convert the hours into minutes.
Currently I have a value which give me the number of hours before the dot and the number of minutes after the dot, for example 6.10 is 6 hours and 10 minute.
Can i use a regular expression to look for the value before the dot and multiply by 60 (to get minutes) and then add the value after the dot (which is already in minutes)?
So as per the example used before, it would do:
(6 * 60) + 10
Thank you!
There's a STRTOK function to tokenize a string and then it's just:
select '12.34' as x,
cast(strtok(x,'.',1) as int) * 60 + cast(strtok(x,'.',2) as int)
If your value "6.10" is stored as a string, convert it to a number first:
SET #Input = CAST(#InputString AS FLOAT)
Then, use Modulus and Floor.
Total Minutes = The fractional part * 100 + the whole number part * 60.
So if your value 6.10 is contained in a variable named #Input, then you can get the value you wish with
SET #Output = (#Input % 1) * 100 + FLOOR(#Input, 0) * 60
If it's in a table then something more like this would be appropriate:
SELECT (Input % 1) * 100 + FLOOR(Input, 0) * 60 Output
FROM Table
The above only works if minutes are zero padded, e.g. 6 hours five minutes = 6.05. If you instead represent minutes without padding (6 hours five minutes = 6.5) then use the method that under suggests.
Regular expressions is probably an overkill for such a simple string manipulation. All you need is INDEX function to get the location of the dot and SUBSTR function to get hours and minutes.
Dot position:
select INDEX([yourstring], '.')
Hours (before the dot):
select SUBSTR([yourstring], 1, INDEX([yourstring], '.') - 1)
Minutes (after the dot):
select SUBSTR([yourstring], INDEX([yourstring], '.') + 1)