如何写日期&时移查询?

时间:2016-05-23 21:01:53

标签: sql oracle

有人可以帮我写一个CASE查询。使用列名PERFORM_DT_TM - 日期&时间格式“MM-DD-YYYY HH-MI-SS”

表名PERFORM_RESULT

我想要的结果是这样的:

BETWEEN'06:00:00'AND'14:29:59' THEN 'First Shift'
BETWEEN'14:30:00'AND'22:59:59' THEN 'Second Shift'
BETWEEN '23:00:00' AND'05:59:59' THEN 'Third Shift'
ELSE 'UNKNOWN'

4 个答案:

答案 0 :(得分:1)

假设这是针对Oracle的,并假设PERFORM_DT_TM列是数据类型DATE ...

我们可以使用TO_CHAR函数格式化时间部分。例如:

TO_CHAR( t.perform_dt_tm,'HH24:MI' )

我们可以在CASE表达式中进行字符串比较。例如:

SELECT CASE
         WHEN TO_CHAR(t.perform_dt_tm,'HH24:MI') >= '06:00' 
          AND TO_CHAR(t.perform_dt_tm,'HH24:MI')  < '14:30'
         THEN 'First Shift'
         WHEN TO_CHAR(t.perform_dt_tm,'HH24:MI') >= '14:30'
          AND TO_CHAR(t.perform_dt_tm,'HH24:MI')  < '23:00'
         THEN 'Second Shift'
         WHEN TO_CHAR(t.perform_dt_tm,'HH24:MI') >= '23:00'
           OR TO_CHAR(t.perform_dt_tm,'HH24:MI')  < '06:00'
         THEN 'Third Shift'
         ELSE 'Unknown'
       END AS which_shift
     , t.perform_dt_tm
     , ...
  FROM ... t

注意:这是基于列的数据类型为DATE的假设,并且这是针对Oracle的。如果列是不同的数据类型,那么我们需要调整“时间”部分的提取方式。

TO_CHAR函数特定于Oracle。如果这是针对Oracle以外的数据库,我们需要调整提取时间部分的表达式。 (例如,MySQL的DATE_FORMAT)

可以更简洁地获得等效结果:

SELECT CASE
         WHEN TO_CHAR(t.perform_dt_tm,'HH24')     < '06:00'
         THEN 'Third Shift'
         WHEN TO_CHAR(t.perform_dt_tm,'HH24:MI')  < '14:30'
         THEN 'First Shift'
         WHEN TO_CHAR(t.perform_dt_tm,'HH24')     < '23:00'
         THEN 'Second Shift'
         WHEN TO_CHAR(t.perform_dt_tm,'HH24')     < '24:00'
         THEN 'Third Shift'
         ELSE 'Unknown'
       END AS which_shift
     , t.perform_dt_tm
     , ...
  FROM ... t

答案 1 :(得分:1)

您可以使用to_char(PERFORM_RESULT, 'HH24:MI')获取该日期的小时和分钟数;这不需要秒。

对于23:0005:59,您需要检查两个范围,因为BETWEEN不知道时钟环绕,它只是进行文本比较。

SELECT CASE
    WHEN to_char(PERFORM_DT_TM, 'HH24:MI') BETWEEN '06:00' AND '14:29' THEN 'First Shift'
    WHEN to_char(PERFORM_DT_TM, 'HH24:MI') BETWEEN '14:30' AND '22:59' THEN 'Second Shift'
    WHEN to_char(PERFORM_DT_TM, 'HH24:MI') BETWEEN '23:00' AND '23:59' THEN 'Third Shift'
    WHEN to_char(PERFORM_DT_TM, 'HH24:MI') BETWEEN '00:00' AND '05:59' THEN 'Third Shift'
    ELSE 'UNKNOWN'
END

您还可以利用案例按顺序进行测试以简化案例的事实,因为如果前一案例已排除了案例的开头,则不必检查案例的开头。

SELECT CASE
    WHEN to_char(PERFORM_DT_TM, 'HH24:MI') <= '05:59' THEN 'Third Shift'    
    WHEN to_char(PERFORM_DT_TM, 'HH24:MI') <= '14:29' THEN 'First Shift'
    WHEN to_char(PERFORM_DT_TM, 'HH24:MI') <= '22:59' THEN 'Second Shift'
    WHEN to_char(PERFORM_DT_TM, 'HH24:MI') <= '23:59' THEN 'Third Shift'
    ELSE 'UNKNOWN'
END

答案 2 :(得分:1)

假设PERFORM_DT_TM属于datetime数据类型(应该是),您不需要像'MM-DD-YYYY'或类似的格式模型;你最好使用数字比较而不是词典。

一天中的时间是PERFORM_DT_TM - trunc(PERFORM_DT_TM)trunc保持相同的日期,但将时间部分截断回00:00:00 AM,因此差异只是PERFORM_DT_TM中存储的日期时间的时间部分。然而,这个&#34;时间组件&#34;表示为1天的分数;比较小时数,将小时数除以24(或者将时差乘以24;我说明下面的第一个选择)。

假设您的表名为MY_TABLE,您的案例表达式可以编写(使用&#34; with子句&#34;在Oracle 11.1及更高版本中可用),如下所示:

with p as (
        select PERFORM_DT_TM - trunc(PERFORM_DT_TM) as PERF_TM [, other columns] 
        from MY_TABLE
     )
select [other columns, perhaps PERF_TM,]
       case
       when PERF_TM >=    6/24 and PERF_TM <  14.5/24 then "First Shift"
       when PERF_TM >= 14.5/24 and PERF_TM <    23/24 then "Second Shift"
       when PERF_TM <     6/24  or PERF_TM >=   23/24 then "Third Shift"
       else                                                "Error/Unknown"
       end as SHIFT
from p;

答案 3 :(得分:1)

Oracle安装程序

CREATE TABLE PERFORM_RESULT ( PERFORM_DT_TM DATE );

INSERT INTO PERFORM_RESULT
SELECT TIMESTAMP '2016-05-23 00:00:00' FROM DUAL UNION ALL
SELECT TIMESTAMP '2016-05-21 12:00:00' FROM DUAL UNION ALL
SELECT TIMESTAMP '2016-05-19 15:00:00' FROM DUAL;

查询1 - 使用一天中的分数进行比较

SELECT PERFORM_DT_TM,
       CASE WHEN time >= 6/24 AND time < 14.5/24  THEN 'First Shift'
            WHEN time >= 14.5/24 AND time < 23/24 THEN 'Second Shift'
                                                  ELSE 'Third Shift'
            END AS shift
FROM   (
  SELECT PERFORM_DT_TM,
         PERFORM_DT_TM - TRUNC( PERFORM_DT_TM ) AS time
  FROM   PERFORM_RESULT
);

查询2 - 使用间隔进行比较

SELECT PERFORM_DT_TM,
       CASE WHEN time >= INTERVAL  '6' HOUR
            AND  time <  INTERVAL '14' HOUR + INTERVAL '30' MINUTE
            THEN 'First Shift'
            WHEN time >= INTERVAL '14' HOUR + INTERVAL '30' MINUTE
            AND  time <  INTERVAL '23' HOUR
            THEN 'Second Shift'
            ELSE 'Third Shift'
            END AS shift
FROM   (
  SELECT PERFORM_DT_TM,
         NUMTODSINTERVAL( PERFORM_DT_TM - TRUNC( PERFORM_DT_TM ), 'DAY' ) AS time
  FROM   PERFORM_RESULT
);

(或者您可以将所有时间转换为分钟间隔 - 即INTERVAL '360' MINUTEINTERVAL '870' MINUTEINTERVAL '1380' MINUTE作为边界)

<强>输出

(两者都输出相同的结果)

PERFORM_DT_TM       SHIFT      
------------------- ------------
2016-05-23 00:00:00 Third Shift  
2016-05-21 12:00:00 First Shift  
2016-05-19 15:00:00 Second Shift