I am trying to perform the below mentioned code from Microsoft SQL server to snowflake however, am successful so far. Can someone help please?
MSSQL Code
convert(varchar(10),(DATEDIFF(s,A.Date_Time,CURRENT_TIMESTAMP))/86400) + 'Days '
+ convert(varchar(10),((DATEDIFF(s,A.Date_Time,CURRENT_TIMESTAMP))% 86400) /24) + 'Hours '
+ convert(varchar(10),(((DATEDIFF(s,A.A.Date_Time,CURRENT_TIMESTAMP)) % 86400) %3600)/60) + 'Mins'
as [Waiting Pending Time]
Snowflake - here you may find the first line only as am testing atm
convert(to_varchar(10),(datediff(second,a.DateTime,current_timestamp)/86400) + "'Days'") as datediff
Can someone help pls?
Thanks
You don't need to calculate them manually, DATEDIFF can handle it:
with mytable1 as (
select '2021-01-02 15:30' Date_Time )
select DATEDIFF( days, Date_Time, CURRENT_TIMESTAMP ) || ' Days ' ||
DATEDIFF( hours, Date_Time, CURRENT_TIMESTAMP ) % 24 || ' Hours ' ||
DATEDIFF( second, Date_Time, CURRENT_TIMESTAMP ) % 60 || ' Seconds ' AS result
from mytable1;
+-----------------------------+
| RESULT |
+-----------------------------+
| 195 Days 14 Hours 6 Seconds |
+-----------------------------+
Related
I have a column in a table that stores the number of minutes as a numeric(18,4) field named [course_access_minutes].
The stored values come from a blackboard database and look like this:
0.0500
0.0667
0.3667
up to
314.0833
625.8167
How do I convert these to time hh:mm, I've had a good look at the database documentation and all I can find is
course_access_minutes numeric(18,4) This is the number of minutes that the user accesses this course in total during this login session.
Can I assume that I can make a direct conversion from minutes into hours? I think I will take any values below 1 as 0 minutes. What is the best way to do this in SQL? Thanks in advance for your help.
Try this
SELECT CONVERT(varchar, DATEADD(s, 625.8167 * 60, 0), 108)
If the duration is longer than 24 hours you can use this
SELECT CONVERT(varchar, CAST(1877.4501 * 60 AS int) / 3600)
+ RIGHT(CONVERT(varchar, DATEADD(s, 1877.4501 * 60, 0), 108), 6)
You could use FLOOR like this
DECLARE #SampleData AS TABLE
(
Minutes numeric(18,4)
)
INSERT INTO #SampleData
VALUES
( 0.0500),
( 1.0500),
( 30.0500),
( 80.0500),
( 314.0833),
( 625.8167)
SELECT CONCAT(floor(sd.Minutes/60),':', CASE WHEN sd.Minutes - floor(sd.Minutes/60)*60 < 1 THEN '0'
ELSE FLOOR(sd.Minutes - floor(sd.Minutes/60)*60 )
END) AS hours
FROM #SampleData sd
Returns
hours
0:0
0:1
0:30
1:20
5:14
10:25
WITH _Samples AS (
SELECT CONVERT(numeric(18, 4), 0.0500) [course_access_minutes]
UNION ALL SELECT 0.0667
UNION ALL SELECT 0.3667
UNION ALL SELECT 314.0833
UNION ALL SELECT 625.8167
)
SELECT
S.course_access_minutes,
-- split out the number
FLOOR(S.course_access_minutes / 60) [hours],
FLOOR(S.course_access_minutes % 60) [minutes],
FLOOR((S.course_access_minutes - FLOOR(S.course_access_minutes)) * 60) [seconds],
-- to a string
CONVERT(varchar(10), FLOOR(S.course_access_minutes / 60))
+ ':' + RIGHT('00' + CONVERT(varchar(10), FLOOR(S.course_access_minutes % 60)), 2)
+ ':' + RIGHT('00' + CONVERT(varchar(10), FLOOR((S.course_access_minutes - FLOOR(S.course_access_minutes)) * 60)), 2) [time_string],
-- You could consider converting to the time data type if the values will never exceed the limit
-- time supports 00:00:00.0000000 through 23:59:59.9999999
-- 0 through 1439.9833333 ... 23 * 60 = 1380 + 59 = 1439 + (59 / 60) = 1439.9833333
-- (see: https://learn.microsoft.com/en-us/sql/t-sql/data-types/time-transact-sql)
CONVERT(time,
CONVERT(varchar(10), FLOOR(S.course_access_minutes / 60))
+ ':' + RIGHT('00' + CONVERT(varchar(10), FLOOR(S.course_access_minutes % 60)), 2)
+ ':' + RIGHT('00' + CONVERT(varchar(10), FLOOR((S.course_access_minutes - FLOOR(S.course_access_minutes)) * 60)), 2)
) [time]
FROM
_Samples S
(It wouldn't be difficult to further this idea and split out the fractional seconds as well.)
Which yields:
course_access_minutes hours minutes seconds time_string time
---------------------- ------ -------- -------- ------------ ----------------
0.0500 0 0 3 0:00:03 00:00:03.0000000
0.0667 0 0 4 0:00:04 00:00:04.0000000
0.3667 0 0 22 0:00:22 00:00:22.0000000
314.0833 5 14 4 5:14:04 05:14:04.0000000
625.8167 10 25 49 10:25:49 10:25:49.0000000
Note that this is going to be like Greg's answer, but I wanted to explain and simplify it.
You have minutes, so dividing them by 60 and flooring it (removing the decimal) gives the hours (without the minutes).
If you take the total minutes again, and remove (mod it by) the floored hours - which requires conversion to minutes by multiplying by 60 - you are left with the remaining minutes by essentially just finding out what is left after taking away that many groups of sixties:
SELECT FLOOR(course_access_minutes / 60) as Hours,
(FLOOR(course_access_minutes) % 60) as Minutes
FROM MyTable
If you want the decimal to appear for the amount of minute fractions (you want the seconds to appear, in decimal form), remove FLOOR.
If you want seconds in real numbers, keep FLOOR and use what Greg had: FLOOR((S.course_access_minutes - FLOOR(S.course_access_minutes)) * 60) for seconds. Be careful with the parenthesis, though, because you can end up accidentally flooring your decimaled minutes and get 0, and then 0*60 is zero:
FLOOR(
(
course_access_minutes -
FLOOR(course_access_minutes)
) * 60
) as Seconds
In a table, I have a column (AvgWaitTime) which stores data value in seconds (Data Type: float), date wise. I have a function which performs some calculation using AvgWaitTime column and other few columns and returns a value in time format. I would to convert the value returned by the function (time format) into seconds (preferrably decimal, if not then int).
select
(datepart(HH, dbo.fnGetMonthlyAverageWaitTime(m.RDate) * 60 * 60) +
datepart(mi, dbo.fnGetMonthlyAverageWaitTime(m.RDate) * 60) +
datepart(s, dbo.fnGetMonthlyAverageWaitTime(m.RDate)))[MonthlyAverageWaitTime]
from TelephonyMTD m
Error: Operand type clash: time is incompatible with int
So, I tried to run this:
select
(datepart(HH, GetDate() * 60 * 60) +
datepart(mi, GetDate() * 60) +
datepart(s, GetDate()))
Now it says, Implicit conversion from data type datetime to int is not allowed. Use the CONVERT function to run this query. Which is true when I looked at the data type conversion chart, I came to know that conversion to int and float is now allowed.
Please advice.
The problem is you are trying to multiply a date/datetime by an integer which doesn't make sense:
GetDate() * 60 * 60
You could simply use DATEDIFF with seconds, to get the value in seconds:
SELECT DATEDIFF(SECOND, '00:00:00', dbo.fnGetMonthlyAverageWaitTime(m.RDate)) AS MonthlyAverageWaitTime
FROM TelephonyMTD AS m
QUICK EXAMPLE
SELECT t.AvgTime,
AvgTimeInSeconds = DATEDIFF(SECOND, '00:00:00', t.AvgTime)
FROM (VALUES
(CAST('00:01:15' AS TIME)),
(CAST('05:36:47' AS TIME))
) AS t (AvgTime);
Which gives:
+----------+------------------+
| AvgTime | AvgTimeInSeconds |
+----------+------------------+
| 00:01:15 | 75 |
| 05:36:47 | 20207 |
+----------+------------------+
Open and Close brackets are the one causing issue for the above error: Please try like below
SELECT (
( Datepart(HH, Getdate()) * 60 * 60 ) +
( Datepart(mi, Getdate()) * 60 ) +
Datepart(s, Getdate())
)
Try to use Below Syntax to convert seconds to day, hour, minute, seconds
DECLARE #sec INT = 86400;
SELECT
CAST(#sec /60/60/24 AS VARCHAR(12)) + ' Days,'
+ CAST(#sec /60/60 % 24 AS VARCHAR(12))+ ' Hours,'
+ CAST(#sec /60 % 60 AS VARCHAR(2)) + ' Minutes, '
+ CAST(#sec % 60 AS VARCHAR(2)) + ' Seconds.';
I have 2 columns in my table in sql server – [Occurrence Time (NT)] and [Clearance Time(NT)] having the format yyyy-mm-dd hh:mm:ss and a third column [Outage Duration] with the format hh:mm:ss
[Identifier] | [Occurrence Time(NT)] | [Clearance Time(NT)] | [Outage Duration]
4 | 2014-12-28 15:06:33.000 | 2014-12-28 15:18:18.000 | 00:11:45.000
Outage duration is calculated as the difference of [Occurrence Time (NT)] and [Clearance Time(NT)]
Currently my code to do this is as follows :
select distinct a.[Identifier]
,a.[Occurrence Time(NT)]
,a.[Clearance Time(NT)]
,cast((cast(a.[Clearance Time(NT)] as datetime) - cast(a.[Occurrence Time(NT)]as datetime)) as time )
as [Outage Duration]
from final_report_2 a
The cast is just a failsafe as both the columns are already datetime. This code works for all cases where [Occurrence Time (NT)] and [Clearance Time(NT)] fall on the same day i.e. the outage is within 24 hours
For e.g in above row no. 4 both have 28th as the day and thus the outage is calculated correctly.
But the outage duration is wrongly calculated in case of different days.
2678 | 2014-12-28 12:50:04.000 | 2014-12-31 23:59:59.000 | 11:09:55.000
In row 2678 the time should be 83:09:55 instead of 11:09:55.
So I need to factor in the difference of the days as well and then calculate the [Outage duration] in hh:mm:ss format.
One of the possible ways to do this is as follows :
(23:59:59 – 12:50:04) + 00:00:01 + ((31-28-1)*24):00:00 + 23:59:59
where the first part calculates the time of the first day , then the second part calculates the no. of whole days in between the [Occurrence Time (NT)] and [Clearance Time(NT)] and multiplies it by 24 and the final part represents the time of the final day.
How can I implement the above in sql server ? Can it be done using DATEPART or DATEADD functions?
you need to use datediff function.
First find the difference in seconds between the two dates.
select Datediff(SECOND, [Clearance Time(NT)], [Occurrence Time(NT)])
Now convert the seconds to hh:mm:ss using this code.
DECLARE #TimeinSecond INT
SET #TimeinSecond = 86399 -- Change the seconds
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)
Change your query something like this.
SELECT DISTINCT a.[Identifier],
a.[Occurrence Time(NT)],
a.[Clearance Time(NT)],
RIGHT('0' + Cast(Datediff(SECOND, [Clearance Time(NT)],[Occurrence Time(NT)]) / 3600 AS VARCHAR), 2)
+ ':'
+ RIGHT('0' + Cast((Datediff(SECOND, [Clearance Time(NT)],[Occurrence Time(NT)]) / 60) % 60 AS VARCHAR), 2)
+ ':'
+ RIGHT('0' + Cast(Datediff(SECOND, [Clearance Time(NT)],[Occurrence Time(NT)]) % 60 AS VARCHAR), 2) [Outage Duration]
FROM final_report_2 a
Reference: conversion of seconds to hh:mm:ss referred from this link
Good old SQL DATEDIFF.
Here's the duration function I use. All wrapped up in a UDF.
CREATE FUNCTION fDuration(#DtStart DATETIME, #DtEnd DATETIME)
RETURNS VARCHAR(10)
AS
BEGIN
RETURN (
SELECT
CONVERT(VARCHAR(10), t.Hours) + ':' +
RIGHT('00' + CONVERT(VARCHAR(10), t.Minutes), 2) + ':' +
RIGHT('00' + CONVERT(VARCHAR(10), t.Seconds - (t.Hours * 60 * 60) - (t.Minutes) * 60), 2) as Value
FROM (
SELECT
t.Hours,
ABS(t.Seconds / 60 - (t.Hours * 60)) as Minutes,
t.Seconds
FROM (
SELECT
DATEDIFF(SECOND, #DtStart, #DtEnd) as Seconds,
DATEDIFF(SECOND, #DtStart, #DtEnd)/60/60 AS Hours) t
) t)
END
USAGE:
SELECT dbo.fDuration('2014-12-28 12:50:04.000', '2014-12-31 23:59:59.000')
RETURNS :
83:09:55
In your case, you can modify your query like this
SELECT DISTINCT a.[Identifier],
a.[Occurrence Time(NT)],
a.[Clearance Time(NT)],
dbo.fDuration(a.[Occurrence Time(NT)], a.[Clearance Time(NT)]) as [Outage Duration]
FROM final_report_2 a
Or even add [Outage Duration] as a Computed field in final_report_2 with formula
dbo.fDuration([Occurrence Time(NT)],[Clearance Time(NT)])
Then it becomes a simple select...
SELECT DISTINCT a.[Identifier],
a.[Occurrence Time(NT)],
a.[Clearance Time(NT)],
a.[Outage Duration]
FROM final_report_2 a
Note
Hours are not prefixed with a '0'. This allows for negative durations.
Hope that helps
I want to get the Date difference in hours and minutes and to achieve that I have used this query in SQL Server:
Cast(SUM(DATEDIFF(second, fromtime, totime) / 60 / 60 % 24) as varchar(20)) + ' hours '
+CAST(SUM(DATEDIFF(second, fromtime, totime) / 60 % 60)as varchar(20))+' minutes ' as [TotalTime]
It returns the following Output:
TotalTime
---------------------
16 Hours 120 Minutes
3 Hours 90 Minutes
but the expected output is:
TotalTime
----------------------
18 Hours 0 Minutes
4 Hours 30 Minutes.
Can anyone help me to solve this issue?
Your query is perfect, All you need to do is to write a outer query over it. Something like below
select case when t.minutes>60 then t.hours+(t.minutes/60) else t.hours end as hours,
case when t.minutes>60 then t.minutes%60 else t.minutes end as minutes
from
(
select
Cast(SUM(DATEDIFF(second, fromtime, totime) / 60 / 60 % 24) as varchar(20)) as hours
+CAST(SUM(DATEDIFF(second, fromtime, totime) / 60 % 60)as varchar(20)) as minutes
from tablename
)as t
Good morning guys.
I need your help again.
Im doing a sales report but I cant get the output I want.
My code is this:
Select Cast(TIME As Varchar(100))+ '-' + CAST(DATEADD( MINUTE, 59, TIME)As varchar(100)) As TIME, SUM (TOTAL) as HOURLY_SALES
From tblSales
Where Mall = 'Mall1' and ORDATE = '6/2/2014' and VOID = 'N'
Group By OTIME
and its given me this output:
Time HOURLY_SALES
12:00-Jan 1 1900 12:59PM 295.00
13:00-Jan 1 1900 1:59PM 2122.86
14:00-Jan 1 1900 2:59PM 2230.00
15:00-Jan 1 1900 3:59PM 1800.00
16:00-Jan 1 1900 4:59PM 3090.00
17:00-Jan 1 1900 5:59PM 880.00
18:00-Jan 1 1900 6:59PM 652.86
19:00-Jan 1 1900 7:59PM 1890.00
20:00-Jan 1 1900 8:59PM 2272.86
21:00-Jan 1 1900 9:59PM 520.00
I dont know where the date come from.
Please help me to remove the date.
The output shoulbe like this:
Time HOURLY_SALES
12:00- 12:59PM 295.00
13:00- 1:59PM 2122.86
14:00- 2:59PM 2230.00
15:00- 3:59PM 1800.00
16:00- 4:59PM 3090.00
17:00- 5:59PM 880.00
18:00- 6:59PM 652.86
19:00- 7:59PM 1890.00
20:00- 8:59PM 2272.86
21:00- 9:59PM 520.00
I'm using visual studio 2010 and ms sql server 2008
Hope you'll help me.
Thank you very much.
How about doing this instead?
select (cast(datepart(hour, [time]) as varchar(255)) + ':00 -' +
cast(datepart(hour, [time]) as varchar(255)) + ':59'
) as [time],
SUM (TOTAL) as HOURLY_SALES
From tblSales
Where Mall = 'Mall1' and ORDATE = '6/2/2014' and VOID = 'N'
Group By cast(datepart(hour, [time]) AS VARCHAR(255));