Warm tip: This article is reproduced from serverfault.com, please click

Time Difference Calculation on SAP HANA Cloud

发布于 2020-11-30 11:13:58

I want to calculate the difference between Occurence_TimeStamp and Response_TimeStamp using a calculated column.

I have used SECONDS_BETWEEN("Occurence_TimeStamp", "Response_TimeStamp") to convert the difference in seconds.

The challenge I am facing now is that for Response Time that occurs in the following day, SAP HANA returns a negative value.

E.g 00:32:00 - 23:41 should return 3,060 seconds but HANA returned -83340. My solution is to add 86,400 (60x60x24) to every time difference affected in order to resolve the issue.

Here is the code I'm using (TimeDrill = Response_Time - Occurence_Time)

CASE "TimeDrill" WHEN "TimeDrill" > 0 then "TimeDrill" ELSE "TimeDrill"+86400 END

Error message below:

enter image description here

Thanks

Questioner
Akby
Viewed
0
Lars Br. 2020-12-01 16:06:02

It looks like the timestamps in your scenario are, in fact time of the day timestamps (e.g. not 2020/12/01 08:48:12 but just 08:48:12).

In that case, the SECONDS_BETWEEN function needs to convert the time values into HANA timestamps (date + time) first.

With no date provided, this yields the 0001-01-01 as the date component.

Looking at that in code gives us this:

SELECT 
      to_timestamp ('00:32:00', 'HH24:MI:SS') "early_TS"
    , TO_TIMESTAMP ('23:41:00', 'HH24:MI:SS') "late_TS"
    , seconds_between ( to_timestamp ('00:32:00', 'HH24:MI:SS'),  TO_TIMESTAMP ('23:41:00', 'HH24:MI:SS')) "early_first"
    , seconds_between ( TO_TIMESTAMP ('23:41:00', 'HH24:MI:SS'),  to_timestamp ('00:32:00', 'HH24:MI:SS')) "late_first"
    
 FROM 
    DUMMY 

early_TS           |late_TS            |early_first|late_first|
-------------------|-------------------|-----------|----------|
0001-01-01 00:32:00|0001-01-01 23:41:00|      83340|    -83340|

Important to note here is that the difference between those two timestamps has the same absolute number of seconds. The sign simply indicates the "direction" of the difference, e.g. which of the two timestamps was larger than the other.

For your calculation you could just use the ABS() (absolute) function to always get the value without the sign.

---- Update based on the comments and re-reading the original question

The underlying assumption seems to be that the RESPONSE_TS always is a timestamp after the OCCURRENCE_TS. This makes sense in a cause-effect-kind of model. E.g. something occurs and then there is a response to that occurrence.

In that case, a time of day timestamp of a response that is seemingly earlier than the occurrence has to be interpreted to have happened on the following day. In the OP's example the response at 00:32:00 is supposed to happen 3060 seconds after the occurrence at 23:41:00.

To do that, we need a case-differentiation in the SQL statement as the actual time of day data does not contain this information.

WITH event_ts AS 
    (SELECT   
          TO_TIMESTAMP ('23:41:00', 'HH24:MI:SS') "OCCURRENCE_TS"
        , to_timestamp ('00:32:00', 'HH24:MI:SS') "RESPONSE_TS" 
    FROM 
        DUMMY)
SELECT 
      "OCCURRENCE_TS" -- this is considered to ALWAYS happen BEFORE the RESPONSE
    , "RESPONSE_TS"   -- this is considered to ALWAYS happen AFTER the OCCURRENCE
   , CASE 
        WHEN ("RESPONSE_TS" > "OCCURRENCE_TS") THEN  -- "RESPONSE_AFTER_BUT_SAME_DAY"
            seconds_between ("OCCURRENCE_TS", "RESPONSE_TS")
        ELSE -- "RESPONSE_AFTER_BUT_NEXT_DAY"
            seconds_between ("OCCURRENCE_TS", ADD_DAYS("RESPONSE_TS", 1))
     END "SECONDS_BETWEEN_OCCURRENCE_AND_RESPONSE"
FROM 
    event_ts;
    

In this solution, whenever the response is seemingly happening earlier than the occurrence, one day is added to the RESPONSE_TS to shift it to the following day.

OCCURRENCE_TS      |RESPONSE_TS        |SECONDS_BETWEEN_OCCURRENCE_AND_RESPONSE|
-------------------|-------------------|---------------------------------------|
0001-01-01 23:41:00|0001-01-01 00:32:00|                                   3060|

It's important to understand that this approach re-computes information based on the rule about what it means when RESPONSE_TS is smaller than OCCURRENCE_TS. As this is not necessarily obvious and may be used in several places across the read data model, it may be worthwhile putting this into a user-defined scalar function.