SELECT SUM for time - sql

I have a Table in SQL server with a column "Time" having data type as time(7). Need to call the sum of this column, and when I use the following statement, it returns result as integer only.
Eg. If total time is 1:30:00,I expect result as 1.5. But the code I use doesn't get me this, it get me result as 1. Please check if you have a solution.
The code I used is
SELECT SUM(DATEPART(ss,Time) + DATEPART(mi,Time)*60 + DATEPART(hh,Time)*3600)/3600 AS TotalTime FROM dbo.Table

SELECT (
DATEPART(hh,Time) +
DATEPART(mi,Time) / 60.0 +
DATEPART(ss,Time) / 3600.0
) AS TotalTime
FROM dbo.Table

Try below - you don't need sum() function here and in your case, it is showing 1 because your result is 5400/3600 which is 1 but you need to add a float value as you are expecting float result
SELECT (DATEPART(ss,'1:30:00') + DATEPART(mi,'1:30:00')*60 +
DATEPART(hh,'1:30:00')*3600)/3600.00
AS TotalTime FROM dbo.Table

Try this, you can change the datepart argument based on your needs here is the full list
SELECT SUM(CAST(DATEDIFF(MINUTE, '00:00:00', [Time]) as float)/60) AS TotalHours FROM [dbo].[Table]

When you divide some value by int type, the result will be also int (the fraction is just dropped). Therefore, you need to convert a divider of 3600 from int to decimal:
SELECT SUM(DATEPART(ss,Time) + DATEPART(mi,Time)*60 + DATEPART(hh,Time)*3600)/CONVERT(DECIMAL(16,4), 3600) AS TotalTime FROM dbo.Table

If you want the difference in decimal hours, then do the following:
Convert the time values to seconds.
Sum the seconds.
Divide by 60 * 60
So:
select sum(datediff(second, 0, v.t)) / (60.0 * 60)
from (values (convert(time, '00:10:01')),
(convert(time, '01:00:03'))
) v(t)
There is no reason to break the value in to component parts. That just seems unnecessarily complicated.

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

Return DATEDIFF in milliseconds on SQL Server 2008R2

I have a SQL query returning a value for x, which is a timestamp, mapped to a C# object of type long:
SELECT DATEDIFF(second, { d '1970-01-01'}, dateCompleted) AS x
The above statement works. However, I need to get the timestamp to return the value in milliseconds rather than seconds. In SQL Server 2016 I can do this:
SELECT DATEDIFF_BIG(millisecond, { d '1970-01-01'}, dateCompleted) AS x
...and that works great. However, I'm stuck on SQL Server 2008 R2.
I could return the values and do some post-processing in C# to multiply x by 1000 but I wondered if there's a way to handle this in the query itself. I've tried a simple multiplication but that yields an Arithmetic overflow error:
SELECT DATEDIFF(second, { d '1970-01-01'}, dateCompleted) * 1000 AS x
Could anyone suggest how to accomplish this?
Thanks.
DATEDIFF returns an INT so it cannot be used to return difference in millisecond if the two dates are far (approx. 25 days) apart. However you could calculate the difference in seconds, BIGINT multiply by 1000, and add the milliseconds:
SELECT DATEDIFF(SECOND, '1970-01-01', dateCompleted)
* CAST(1000 AS BIGINT)
+ DATEPART(MILLISECOND, dateCompleted)
Assuming you want UNIX timestamp you also need to add the timezone offset to the result (I hope you stored it along with date completed).
How about using cast() or convert()?
SELECT DATEDIFF(second,{ d '1970-01-01'},dateCompleted) * convert(bigint, 1000) AS x
Perhaps a variable?
DECLARE #milli BIGINT;
SET #milli = DATEDIFF(second,{ d '1970-01-01'},dateCompleted) * 1000.0;
SELECT #milli;
Datediff return int value so second will have issue with int data type.
you can get the minutes or days and multiple with 60 for getting seconds
SELECT DATEDIFF(m,{ d '1970-01-01'},getdate()) * 1000 * 60

Get only month and year in SQL Server

I want to fetch only month and year from a date column in SQL Server.
Example: if today's date is 02/03/2019, then I want 0319.
Note: I want the result in same order (2 digit month and 2 digit year). Zero should not be removed from month.
As an alternative approach, you could go for:
RIGHT(REPLACE(CONVERT(varchar(8),DateColumn,3),'/',''),4)
You can create a number using:
select month(datecol) * 100 + (year(datecol) % 100)
Prepending the zeros requires a bit more work:
select right('0' + convert(varchar(255), month(datecol) * 100 + (year(datecol) % 100)), 4)
Or, you can use format():
select format(datecol, 'MMyy')
You can try this
substring(convert(nvarchar,#date,12),3,2) + left(convert(nvarchar,#date,12),2)
You can create an user defined function, and then apply to your column/s
create function udf_Getmonthyear(#date as date)
RETURNS nchar(4)
BEGIN
DECLARE #d_format nchar(6) = (select convert(nvarchar,#date,12))
RETURN (select SUBSTRING(#d_format,3,2) + left(#d_format,2))
end
go
Use function DATEPART in TSQL to get any part of a DateTime value. e.g:
DATEPART(yy,datecol) gives you 4 digit year part of a DateTime column (e.g: datecol), using the % (modulus) operator you can get 2 digit year DATEPART(yy,datecol)%100.
DATEPART(mm,datecol) gives you month part of the datecol field.
select Right('0'+cast(DATEPART(mm,datecol) as varchar(2)),2) +
Right('0'+cast(DATEPART(yy,datecol)%100 as varchar(2)),2) MonthYearPart
from MyTable
Regards

T-SQL: how to update time column with random times

I am using SQL Server 2012 and T-SQL. I have a time column of 200 rows with different times (hh:mm:ss). I need to update it with random times. So all the data times I have now will be updated with new data times. Thank you!
Here is one method:
select cast(dateadd(second, rand(checksum(newid()))*60*60*24, 0) as time)
UPDATE <YOUR_TABLE> SET <TIME_COLUMN> = DATEADD(second, Rand(Cast(Newid() AS VARBINARY)) * datediff(second,'00:00:00', '23:59:59'), '00:00:00')
Assume you have the following 3 rows with a time column that contains different times:
CREATE TABLE table_with_times (timecolumn TIME);
INSERT INTO table_with_times VALUES ('20:00:00'),('05:00:59'),('22:30:50');
You can update each time column to new random time by computing random values for hour/minutes/seconds:
select * from table_with_times;
UPDATE table_with_times SET timecolumn = CAST(RIGHT('00' + CAST(ABS(CHECKSUM(NewId())) % 24 AS VARCHAR(2)),2)+':'+ RIGHT('00' + CAST(ABS(CHECKSUM(NewId())) % 60 AS VARCHAR(2)),2)+':'+ RIGHT('00' + CAST(ABS(CHECKSUM(NewId())) % 60 AS VARCHAR(2)),2) AS TIME);
select * from table_with_times;
Try it on http://sqlfiddle.com/

How to Handle DATEDIFF(MINUTE, '00:00', '24:20') Like scenario?

There is a column in my Table. In which we are storing string value in format 'HH:MM'.During fetching records with this table every things works ok with
DATEDIFF(MINUTE, '00:00', ColumnName)
Problem is when we have Value greater than 23:59.
Its showing error like
Conversion failed when converting date and/or time from character string.
Can anybody suggest me the right approach for achieving this scenario.
If you are storing the value as something other than a time, why not just store the number of minutes and convert to whatever format you want on output?
Otherwise, I would suggest that you simply convert the value to minutes:
select (cast(left(ColumnName, 2) as int) * 60 +
cast(right(ColumnName, 2) as int)
) as Minutes
If you are not using date/time values, there is no requirement for using the functions specifically designed for them.
EDIT:
To handle hours longer than 99, use charindex():
select (cast(left(ColumnName, charindex(':', ColumnName) - 1) as int) * 60 +
cast(right(ColumnName, 2) as int)
) as Minutes
So it sounds like your saving the length of a time period. Try storing it in minutes. My query can handle numbers of different lengths since it's based on the colon.
DECLARE #yourTable TABLE (ColumnName VARCHAR(10));
INSERT INTO #yourTable
VALUES ('100:00'),
('24:20');
SELECT ColumnName,
(hr * 60) + minut AS time_period_in_minutes
FROM #yourTable
CROSS APPLY (SELECT CAST(SUBSTRING(ColumnName,0,CHARINDEX(':',ColumnName)) AS INT),
CAST(SUBSTRING(ColumnName,CHARINDEX(':',ColumnName) + 1,LEN(ColumnName)) AS INT)) CA(hr,minut)
Results:
ColumnName time_period_in_minutes
---------- ----------------------
100:00 6000
24:20 1460
Try to this
select DATEDIFF(MINUTE, '00:00', case when ISDATE(ColumnName)=0 then '00:00' else ColumnName end )