简体   繁体   English

IF 在 SAP HANA 中的时间之间

[英]IF between time in SAP HANA

SELECT SERIES_ROUND(TO_TIMESTAMP(DATE_TIME,'YYYYMMDDHH24MISS'),'INTERVAL 30 MINUTE') as TIME

returns a result like "Mon Nov 02 2020 00:00:00 GMT+0100 (CET)"返回类似“Mon Nov 02 2020 00:00:00 GMT+0100 (CET)”的结果

what i need is to return shift name我需要的是返回班次名称

if time between 08:00:00 and 16:30:00 return SHIFT A
if time between 16:30:00 and 00:15:00 return SHIFT B
if time between 00:15:00 and 08:00:00 return SHIFT C

any help appreciated任何帮助表示赞赏

Something like the following should work:像下面这样的东西应该工作:

SELECT CASE WHEN CAST(TO_TIMESTAMP(DATE_TIME,'YYYYMMDDHH24MISS') AS TIME) BETWEEN TO_TIME ('08:00:00', 'HH24:MI:SS') AND TO_TIME ('16:30:00', 'HH24:MI:SS') THEN 'Shift A'
   WHEN CAST(TO_TIMESTAMP(DATE_TIME,'YYYYMMDDHH24MISS') AS TIME) BETWEEN TO_TIME ('00:15:00', 'HH24:MI:SS') AND TO_TIME ('08:00:00', 'HH24:MI:SS') THEN 'Shift C'
   ELSE 'Shift B' END

This reads a bit like a query that should process the clock-in times of workers or something similar.这读起来有点像应该处理工作人员打卡时间或类似内容的查询。

Therefore I used clock_ins as the name for the timestamped events in my example code.因此,我在我的示例代码中使用clock_ins作为时间戳事件的名称。

To make this work correctly, it helps to make the different computations and data type conversions step by step:为了使其正确工作,它有助于逐步进行不同的计算和数据类型转换:

WITH clock_ins AS (
    SELECT 1 AS ID, to_timestamp('20200101080012', 'YYYYMMDDHH24MISS' ) AS DATE_TIME FROM DUMMY
    UNION ALL 
    SELECT 2 AS ID,  to_timestamp('20200101043135', 'YYYYMMDDHH24MISS' ) AS DATE_TIME FROM DUMMY
    UNION ALL 
    SELECT 3 AS ID, to_timestamp('20200101120056', 'YYYYMMDDHH24MISS' ) AS DATE_TIME FROM DUMMY
    UNION ALL 
    SELECT 4 AS ID, to_timestamp('20200101170012', 'YYYYMMDDHH24MISS' ) AS DATE_TIME FROM DUMMY
),
clock_ins_rounded AS (
    SELECT
        ID
        , SERIES_ROUND(DATE_TIME,'INTERVAL 30 MINUTE') AS clock_in
        , to_time(SERIES_ROUND(DATE_TIME,'INTERVAL 30 MINUTE')) AS clock_in_time
    FROM    
        CLOCK_INS)
SELECT
      id
    , CLOCK_IN
    , clock_in_time 
    , CASE
        WHEN clock_in_time BETWEEN to_time('08:00:00') AND to_time('16:30:00') THEN 
            'SHIFT A'
        WHEN (   clock_in_time >= to_time('16:30:00') 
              OR clock_in_time <= to_time('00:15:00')) THEN 
            'SHIFT B'
        WHEN clock_in_time BETWEEN to_time('00:15:00') AND to_time('08:00:00') THEN 
            'SHIFT C'        
        ELSE 
            'NO SHIFT'
      END AS SHIFT
FROM 
    clock_ins_rounded;


ID|CLOCK_IN           |CLOCK_IN_TIME|SHIFT  |
--|-------------------|-------------|-------|
 1|2020-01-01 08:00:00|     08:00:00|SHIFT A|
 2|2020-01-01 04:30:00|     04:30:00|SHIFT C|
 3|2020-01-01 12:00:00|     12:00:00|SHIFT A|
 4|2020-01-01 17:00:00|     17:00:00|SHIFT B|

The first WITH-clause CLOCK_INS generates the test data and includes at least one case for every rule the OP mentioned.第一个 WITH 子句CLOCK_INS生成测试数据,并为 OP 提到的每个规则至少包含一个案例。

The second WITH-clause CLOCK_INS_ROUNDED performs the "rounding" to the 30 minutes intervals via the SERIES_ROUND function (good choice.).第二个 WITH 子句CLOCK_INS_ROUNDED通过SERIES_ROUND function(不错的选择)执行 30 分钟间隔的“舍入”。 It also takes the result from this rounding and creates a time of day version from it via the TO_TIME() function. This column is then made available as CLOCK_IN_TIME .它还从该舍入中获取结果,并通过TO_TIME() function 从中创建一个时间版本。此列随后可用作CLOCK_IN_TIME

The final and main SELECT clause projects the computed CLOCK_IN timestamp, the CLOCK_IN_TIME column, and also the assigned shifts.最后一个主要的SELECT子句投影计算的CLOCK_IN时间戳、 CLOCK_IN_TIME列以及分配的班次。

The shifts are assigned via a CASE statement.班次是通过CASE语句分配的。 To make this work correctly it is important to use TIME data types for the comparisons.为使其正常工作,使用TIME数据类型进行比较很重要。 Leaving out the TO_TIME( ) conversion for each of the conditions would lead to implicit type conversion and the comparison would be calculated as string comparisons which is NOT what you want for this use case.省略每个条件的TO_TIME( )转换将导致隐式类型转换,并且比较将计算为字符串比较,这不是您想要的此用例。

The other important bit to notice is the rule for SHIFT B .另一个需要注意的重要一点是SHIFT B的规则。 This rule describes an interval between a time before and a time after midnight.该规则描述了午夜之前和之后的时间间隔 As we are dealing with instants of time (actually not even that - it's just time of day data we use) here and not with intervals the BETWEEN comparison would not work correctly for the case of BETWEEN 16:30 AND 00:15 .由于我们在这里处理的是时间瞬间(实际上什至不是那样 - 它只是我们使用的一天中的时间数据)而不是时间间隔,因此对于BETWEEN 16:30 AND 00:15的情况, BETWEEN比较将无法正常工作。 Therefore, we need to take care of this in the code and translate this condition to LARGER (LATER) THAN 16:30 OR SMALLER (EARLIER) THAN 00:15 .因此,我们需要在代码中处理这一点,并将此条件转换为LARGER (LATER) THAN 16:30 OR SMALLER (EARLIER) THAN 00:15

Finally, it is a good idea to include an others branch in CASE statements, so that it is easy to detect data that is not handled by any rule or when rules are not "catching" data that they should have caught.最后,在CASE语句中包含一个others分支是个好主意,这样可以很容易地检测到没有被任何规则处理的数据,或者当规则没有“捕获”它们应该捕获的数据时。

In summary, these are the main points to consider for this requirement:总而言之,这些是此要求要考虑的要点:

  • implement one computation at a time and avoid overly nested expressions (to make the code easier to be read and understood)一次执行一个计算并避免过度嵌套的表达式(以使代码更易于阅读和理解)
  • use an appropriate data type for the comparison semantic (eg use a TIME data type when using time comparisons like "earlier" or "later). This includes both the data to be processed as well as the comparison data in the code.为比较语义使用适当的数据类型(例如,在使用“较早”或“较晚”等时间比较时使用TIME数据类型)。这包括要处理的数据以及代码中的比较数据。
  • when dealing with time-related data types, make sure to understand the differences between date-time, intervals, and time-of-day data在处理与时间相关的数据类型时,确保了解日期时间、间隔和时间数据之间的差异
  • when using CASE statements, include an others case for data that is not handled by the other rules使用CASE语句时,为其他规则未处理的数据包含其他情况

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM