복붙노트

[SQL] 번호 또는 간격 데이터 유형 - 오라클의 날짜를 빼면?

SQL

번호 또는 간격 데이터 유형 - 오라클의 날짜를 빼면?

나는 오라클 DATE 및 INTERVAL 데이터 유형에 대한 내부 작업의 일부에 대한 질문이 있습니다. 당신이 개 DATE 데이터 유형을 뺄 때 오라클 11.2 SQL 참조에 따르면, 결과는 숫자 데이터 형식이 될 것입니다.

피상적 인 시험에서이 사실로 나타납니다 :

CREATE TABLE test (start_date DATE);
INSERT INTO test (start_date) VALUES (date'2004-08-08');
SELECT (SYSDATE - start_date) from test;

숫자 데이터 유형을 반환합니다.

하지만 당신은 할 지금 경우 :

SELECT (SYSDATE - start_date) DAY(5) TO SECOND from test;

당신은 간격 데이터 유형을 얻을. 즉, 오라클은 간격 형식으로 날짜 뺄셈의 번호를 변환 할 수 있습니다.

그래서 지금 내가 직접 괄호 안에 숫자 데이터 형식에 넣어 시도 할 수 생각 (대신 'SYSDATE - START_DATE'을 수행하는 다수의 결과 어쨌든) :

SELECT (1242.12423) DAY(5) TO SECOND from test;

그러나 오류이 결과는 :

ORA-30083: syntax error was found in interval value expression

내 질문은 그래서 여기 무슨 일이야? (SELECT 문 # 3에서 입증 된 바와 같이) 자동으로 간격 형식으로 캐스팅 할 수 없습니다 (SELECT 문 # 1에서 입증 된 바와 같이) 뺀 날짜는 숫자로 연결되어야 것 같다. 그러나 오라클은 대신 원시 번호 (SELECT 문 # 2)에서 퍼팅의 날짜 빼기 식을 사용하는 경우 어떻게 든 할 수있을 것으로 보인다.

감사

해결법

  1. ==============================

    1.좋아, 난 보통 내 자신의 질문에 대답하지 않지만 땜질의 조금 후에, 나는 오라클은 날짜 뺄셈의 결과를 저장 결정적 방법을 알아 낸 것.

    좋아, 난 보통 내 자신의 질문에 대답하지 않지만 땜질의 조금 후에, 나는 오라클은 날짜 뺄셈의 결과를 저장 결정적 방법을 알아 낸 것.

    당신이이 날짜를 뺄 때, 값은 (오라클 11.2 SQL 참조 설명서가있는 것처럼 당신이 믿는) 숫자 데이터 형식이 아닙니다. 날짜 감산 내부 데이터 형식 번호 비 문서화 된 내부 데이터 형식 (NUMBER 내부 데이터 형식 번호 2) 인, (14)이다. 그러나, 실제로 일의 수와 시간 (초)을 나타내는 데 사용 마지막 4 바이트를 나타 내기 위해 사용되는 첫번째 4 바이트로, 2 개 개의 별도 2의 보수 서명 숫자로 저장됩니다.

    양의 정수 차이의 결과 DATE 뺄셈의 예 :

    select date '2009-08-07' - date '2008-08-08' from dual;
    

    결과 :

    DATE'2009-08-07'-DATE'2008-08-08'
    ---------------------------------
                                  364
    
    select dump(date '2009-08-07' - date '2008-08-08') from dual;
    
    DUMP(DATE'2009-08-07'-DATE'2008
    -------------------------------
    Typ=14 Len=8: 108,1,0,0,0,0,0,0
    

    결과가 2 별도의 2의 보수로 표현되는 리콜은 4 개 바이트의 번호를 체결했다. 더 소수가 (이 경우 364일 및 0시간 정확히)가 없기 때문에, 마지막 4 바이트는 모두 0이다 무시할 수 있습니다. 내 CPU는 리틀 엔디안 구조를 가지고 있기 때문에 처음 4 바이트를 들어, 바이트 반전되어 1108 또는 10 진수 (364)입니다 0x16c로 읽어야합니다.

    음의 정수 차이의 결과 DATE 뺄셈의 예 :

    select date '1000-08-07' - date '2008-08-08' from dual;
    

    결과 :

    DATE'1000-08-07'-DATE'2008-08-08'
    ---------------------------------
                              -368160
    
    select dump(date '1000-08-07' - date '2008-08-08') from dual;
    
    DUMP(DATE'1000-08-07'-DATE'2008-08-0
    ------------------------------------
    Typ=14 Len=8: 224,97,250,255,0,0,0,0
    

    다시 말하지만, 나는 리틀 엔디안 기계를 사용하고 있기 때문에, 바이트는 역전이는 2의 보수 부호 바이너리 숫자 인코딩에 있기 때문에 지금은 11111111 11111010 01100001 11011111.에 해당하는, 우리는 숫자가 알고있는 255,250,97,224과 같이해야한다 의심로 -368160 동일 00,000,000 00,000,101 10,011,110 00,100,000 : 가장 왼쪽 이진수는 1. 진수로이를 변환하는 것입니다 부정적인 때문에 우리는 그 결과 2의 보수 (다음 1의 보수를 할 일을 빼기)을 반대해야합니다.

    소수의 차이에 기인하는 DATE 뺄셈의 예 :

    select to_date('08/AUG/2004 14:00:00', 'DD/MON/YYYY HH24:MI:SS'
     - to_date('08/AUG/2004 8:00:00', 'DD/MON/YYYY HH24:MI:SS') from dual;
    
    TO_DATE('08/AUG/200414:00:00','DD/MON/YYYYHH24:MI:SS')-TO_DATE('08/AUG/20048:00:
    --------------------------------------------------------------------------------
                                                                                 .25
    

    이들 2 개 기간 사이의 차이는 0.25 일 6 시간이다.

    select dump(to_date('08/AUG/2004 14:00:00', 'DD/MON/YYYY HH24:MI:SS')
     - to_date('08/AUG/2004 8:00:00', 'DD/MON/YYYY HH24:MI:SS')) from dual;
    
    DUMP(TO_DATE('08/AUG/200414:00:
    -------------------------------
    Typ=14 Len=8: 0,0,0,0,96,84,0,0
    

    차이가 0일 6 시간이기 때문에 지금이 시간, 처음 4 바이트는 우리가 (CPU는 리틀 엔디안 때문에)을 반대하고 얻을 수있는, 마지막 4 바이트 0 것으로 예상된다 84,96 = 01010100 베이스 (2) = 01,100,000 진수 21600. 시간 21,600초를 변환하는 당신에게 우리가 기대의 차이 6 시간을 제공합니다.

    이것은 DATE 공제가 실제로 어떻게 저장되는지 궁금 사람을 도움이되기를 바랍니다.

  2. ==============================

    2.날짜 수학은 숫자를 반환하지 않습니다 때문에 구문 오류가 있지만, 간격을 반환합니다 :

    날짜 수학은 숫자를 반환하지 않습니다 때문에 구문 오류가 있지만, 간격을 반환합니다 :

    SQL> SELECT DUMP(SYSDATE - start_date) from test;
    
    DUMP(SYSDATE-START_DATE)
    -------------------------------------- 
    Typ=14 Len=8: 188,10,0,0,223,65,1,0
    

    먼저 NUMTODSINTERVAL 기능을 사용하여 간격으로 예에서 숫자를 변환해야

    예를 들면 :

    SQL> SELECT (SYSDATE - start_date) DAY(5) TO SECOND from test;
    
    (SYSDATE-START_DATE)DAY(5)TOSECOND
    ----------------------------------
    +02748 22:50:04.000000
    
    SQL> SELECT (SYSDATE - start_date) from test;
    
    (SYSDATE-START_DATE)
    --------------------
               2748.9515
    
    SQL> select NUMTODSINTERVAL(2748.9515, 'day') from dual;
    
    NUMTODSINTERVAL(2748.9515,'DAY')
    --------------------------------
    +000002748 22:50:09.600000000
    
    SQL>
    

    NUMTODSINTERVAL () 함수와 역 캐스팅을 바탕으로, 일부 반올림 번역에 손실 나타납니다.

  3. ==============================

    3.몇 가지 포인트 :

    몇 가지 포인트 :

    오라클 11gR2 SQL 참조 날짜 시간 매트릭스

  4. ==============================

    4.사용 추출물 () 함수는 간격 값에서시 / 분 / 초를 검색 할 수 있습니다. 이 타임 스탬프 열에서 시간을 활용하는 방법, 예를 들어 아래를 참조하십시오. 도움이 되었기를 바랍니다!

    사용 추출물 () 함수는 간격 값에서시 / 분 / 초를 검색 할 수 있습니다. 이 타임 스탬프 열에서 시간을 활용하는 방법, 예를 들어 아래를 참조하십시오. 도움이 되었기를 바랍니다!

    IHB_INS_TS, MAIL_SENT_TS, 추출물 (시간에서 (IHB_INS_TS - MAIL_SENT_TS))를 선택 hourDiff IHB_ADJSMT_WKFL_NTFCTN에서;

  5. ==============================

    5.TIMEDIFF (: 15 PM ','%의 시간 : % i 서 % p 나 '), STR_TO_DATE ('오전 9시 58분 ','%의 시간 : % i 서 % 포인트 ') STR_TO_DATE (07)을 선택

    TIMEDIFF (: 15 PM ','%의 시간 : % i 서 % p 나 '), STR_TO_DATE ('오전 9시 58분 ','%의 시간 : % i 서 % 포인트 ') STR_TO_DATE (07)을 선택

  6. from https://stackoverflow.com/questions/9322935/subtracting-dates-in-oracle-number-or-interval-datatype by cc-by-sa and MIT license