web-gelistirme-sc.com

Oracle'da iki zaman damgası arasındaki farkı milisaniye cinsinden hesaplama

Oracle'da iki zaman damgası arasındaki milisaniye cinsinden zaman farkını nasıl hesaplarım?

46
sarsnake

TIMESTAMP türündeki iki değişkeni çıkardığınızda, platforma bağlı olarak birkaç milisaniye ve/veya mikrosaniye içeren bir INTERVAL DAY TO SECOND elde edersiniz. Veritabanı Windows üzerinde çalışıyorsa, systimestamp genellikle milisaniye olacaktır. Eğer veritabanı Unix üzerinde çalışıyorsa, systimestamp genellikle mikrosaniyeye sahip olacaktır.

  1  select systimestamp - to_timestamp( '2012-07-23', 'yyyy-mm-dd' )
  2*   from dual
SQL> /

SYSTIMESTAMP-TO_TIMESTAMP('2012-07-23','YYYY-MM-DD')
---------------------------------------------------------------------------
+000000000 14:51:04.339000000

Bir INTERVAL DAY TO SECOND öğesinin öğelerini ayıklamak için EXTRACT işlevini kullanabilirsiniz. 

SQL> ed
Wrote file afiedt.buf

  1  select extract( day from diff ) days,
  2         extract( hour from diff ) hours,
  3         extract( minute from diff ) minutes,
  4         extract( second from diff ) seconds
  5    from (select systimestamp - to_timestamp( '2012-07-23', 'yyyy-mm-dd' ) diff
  6*           from dual)
SQL> /

      DAYS      HOURS    MINUTES    SECONDS
---------- ---------- ---------- ----------
         0         14         55     37.936

Daha sonra bu bileşenlerin her birini milisaniyeye dönüştürebilir ve ekleyebilirsiniz.

SQL> ed
Wrote file afiedt.buf

  1  select extract( day from diff )*24*60*60*1000 +
  2         extract( hour from diff )*60*60*1000 +
  3         extract( minute from diff )*60*1000 +
  4         round(extract( second from diff )*1000) total_milliseconds
  5    from (select systimestamp - to_timestamp( '2012-07-23', 'yyyy-mm-dd' ) diff
  6*           from dual)
SQL> /

TOTAL_MILLISECONDS
------------------
          53831842

Bununla birlikte normal olarak, iki TIMESTAMP değeri arasındaki toplam milisaniye sayısını hesaplamak yerine, INTERVAL DAY TO SECOND temsiline sahip olmak veya saat, dakika, saniye vb. İçin ayrı sütunlara sahip olmak daha faydalı olur.

67
Justin Cave

İşte bunu yapmak için depolanmış bir proc:

CREATE OR REPLACE function timestamp_diff(a timestamp, b timestamp) return number is 
begin
  return extract (day    from (a-b))*24*60*60 +
         extract (hour   from (a-b))*60*60+
         extract (minute from (a-b))*60+
         extract (second from (a-b));
end;
/

Up Up Oy Ver Eğer işini ihmal eden Oracle geliştiricisinin saçmalıklarını da yenmek istersen! 

ÇÜNKÜ zaman damgaları ilk kez karşılaştırarak Herkese bir saat kadar sürmeli ...

18
Brian McGinity

Daha kolay çözüm:

SELECT numtodsinterval(date1-date2,'day') time_difference from dates;

Zaman damgaları için:

SELECT (extract(DAY FROM time2-time1)*24*60*60)+ 
(extract(HOUR FROM time2-time1)*60*60)+
(extract(MINUTE FROM time2-time1)*60)+
extract(SECOND FROM time2-time1)
into diff FROM dual;

RETURN diff;
13
pat34515
Select date1 - (date2 - 1) * 24 * 60 *60 * 1000 from Table;
3
phadaphunk

Bunun çok iyi cevaplandığını biliyorum, ancak FONKSİYON'umu herkesle paylaşmak istedim. Yanıtınızın gün, saat, dakika, saniye veya milisaniye cinsinden olmasını isteyip istemediğinizi seçme seçeneği sunar. Gereksinimlerinize göre değiştirebilirsiniz.

CREATE OR REPLACE FUNCTION Return_Elapsed_Time (start_ IN TIMESTAMP, end_ IN TIMESTAMP DEFAULT SYSTIMESTAMP, syntax_ IN NUMBER DEFAULT NULL) RETURN VARCHAR2 IS
    FUNCTION Core (start_ IN TIMESTAMP, end_ IN TIMESTAMP DEFAULT SYSTIMESTAMP, syntax_ IN NUMBER DEFAULT NULL) RETURN VARCHAR2 IS
        day_ VARCHAR2(7); /* This means this FUNCTION only supports up to 99 days */
        hour_ VARCHAR2(9); /* This means this FUNCTION only supports up to 999 hours, which is over 41 days */
        minute_ VARCHAR2(12); /* This means this FUNCTION only supports up to 9999 minutes, which is over 17 days */
        second_ VARCHAR2(18); /* This means this FUNCTION only supports up to 999999 seconds, which is over 11 days */
        msecond_ VARCHAR2(22); /* This means this FUNCTION only supports up to 999999999 milliseconds, which is over 11 days */
        d1_ NUMBER;
        h1_ NUMBER;
        m1_ NUMBER;
        s1_ NUMBER;
        ms_ NUMBER;
        /* If you choose 1, you only get seconds. If you choose 2, you get minutes and seconds etc. */
        precision_ NUMBER; /* 0 => milliseconds; 1 => seconds; 2 => minutes; 3 => hours; 4 => days */
        format_ VARCHAR2(2) := ', ';
        return_ VARCHAR2(50);
    BEGIN
        IF (syntax_ IS NULL) THEN
            precision_ := 0;
        ELSE
            IF (syntax_ = 0) THEN
                precision_ := 0;
            ELSIF (syntax_ = 1) THEN
                precision_ := 1;
            ELSIF (syntax_ = 2) THEN
                precision_ := 2;
            ELSIF (syntax_ = 3) THEN
                precision_ := 3;
            ELSIF (syntax_ = 4) THEN
                precision_ := 4;
            ELSE 
                precision_ := 0;
            END IF;
        END IF;
        SELECT EXTRACT(DAY FROM (end_ - start_)) INTO d1_ FROM DUAL;
        SELECT EXTRACT(HOUR FROM (end_ - start_)) INTO h1_ FROM DUAL;
        SELECT EXTRACT(MINUTE FROM (end_ - start_)) INTO m1_ FROM DUAL;
        SELECT EXTRACT(SECOND FROM (end_ - start_)) INTO s1_ FROM DUAL;
        IF (precision_ = 4) THEN
            IF (d1_ = 1) THEN
                day_ := ' day';
            ELSE
                day_ := ' days';
            END IF;
            IF (h1_ = 1) THEN
                hour_ := ' hour';
            ELSE
                hour_ := ' hours';
            END IF;
            IF (m1_ = 1) THEN
                minute_ := ' minute';
            ELSE
                minute_ := ' minutes';
            END IF;
            IF (s1_ = 1) THEN
                second_ := ' second';
            ELSE
                second_ := ' seconds';
            END IF;
            return_ := d1_ || day_ || format_ || h1_ || hour_ || format_ || m1_ || minute_ || format_ || s1_ || second_;
            RETURN return_;
        ELSIF (precision_ = 3) THEN
            h1_ := (d1_ * 24) + h1_;
            IF (h1_ = 1) THEN
                hour_ := ' hour';
            ELSE
                hour_ := ' hours';
            END IF;
            IF (m1_ = 1) THEN
                minute_ := ' minute';
            ELSE
                minute_ := ' minutes';
            END IF;
            IF (s1_ = 1) THEN
                second_ := ' second';
            ELSE
                second_ := ' seconds';
            END IF;
            return_ := h1_ || hour_ || format_ || m1_ || minute_ || format_ || s1_ || second_;
            RETURN return_;
        ELSIF (precision_ = 2) THEN
            m1_ := (((d1_ * 24) + h1_) * 60) + m1_;
            IF (m1_ = 1) THEN
                minute_ := ' minute';
            ELSE
                minute_ := ' minutes';
            END IF;
            IF (s1_ = 1) THEN
                second_ := ' second';
            ELSE
                second_ := ' seconds';
            END IF;
            return_ := m1_ || minute_ || format_ || s1_ || second_;
            RETURN return_;
        ELSIF (precision_ = 1) THEN
            s1_ := (((((d1_ * 24) + h1_) * 60) + m1_) * 60) + s1_;
            IF (s1_ = 1) THEN
                second_ := ' second';
            ELSE
                second_ := ' seconds';
            END IF;
            return_ := s1_ || second_;
            RETURN return_;
        ELSE
            ms_ := ((((((d1_ * 24) + h1_) * 60) + m1_) * 60) + s1_) * 1000;
            IF (ms_ = 1) THEN
                msecond_ := ' millisecond';
            ELSE
                msecond_ := ' milliseconds';
            END IF;
            return_ := ms_ || msecond_;
            RETURN return_;
        END IF;
    END Core;
BEGIN
    RETURN(Core(start_, end_, syntax_));
END Return_Elapsed_Time;

Örneğin, eğer şu an bu işlevi çağırdıysam (12.10.2018 11: 17: 00.00), Return_Elapsed_Time (TO_TIMESTAMP ('12 .04.2017 12: 00: 00.00 ',' DD.MM.YYYY HH24: MI: SS.FF 'kullanarak) ), SYSTIMESTAMP), şöyle bir şey döndürmeli:

47344620000 milliseconds
2
iamdoubz

Böyle bir prosedür kullanmak daha iyidir:

CREATE OR REPLACE FUNCTION timestamp_diff
(
start_time_in TIMESTAMP
, end_time_in TIMESTAMP
)
RETURN NUMBER
AS
l_days NUMBER;
l_hours NUMBER;
l_minutes NUMBER;
l_seconds NUMBER;
l_milliseconds NUMBER;
BEGIN
SELECT extract(DAY FROM end_time_in-start_time_in)
, extract(HOUR FROM end_time_in-start_time_in)
, extract(MINUTE FROM end_time_in-start_time_in)
, extract(SECOND FROM end_time_in-start_time_in)
INTO l_days, l_hours, l_minutes, l_seconds
FROM dual;

l_milliseconds := l_seconds*1000 + l_minutes*60*1000 + l_hours*60*60*1000 + l_days*24*60*60*1000;
RETURN l_milliseconds;

END;

Telefon ederek kontrol edebilirsiniz:

SELECT timestamp_diff (TO_TIMESTAMP('12.04.2017 12:00:00.00', 'DD.MM.YYYY HH24:MI:SS.FF'), 
                      TO_TIMESTAMP('12.04.2017 12:00:01.111', 'DD.MM.YYYY HH24:MI:SS.FF')) 
            as milliseconds
    FROM DUAL;
1
Konki

I) İki zaman damgası sütunu arasındaki geçen süreyi saniye cinsinden hesaplamanız gerekirse, şunu deneyin:

SELECT ekstresi (günden başlayarak (end_timestamp - start_timestamp)) * 86400 + özü (saatten (end_timestamp - start_timestamp)) * 3600 + özü (dakikadan (end_timestamp - start_timestamp)) * 60 + özü (dakikadan (end_timestamp - start_timestamp))) From table_name

II) Eğer zaman farkını sadece karakter biçiminde göstermek isterseniz, şunu deneyin:

SELECT to_char (end_timestamp - start_timestamp) FROM tablo_adı

0
hany heggy

Yukarıda, bazı sözdizimi hatası var, Lütfen Oracle’da aşağıdakileri kullanın: 

SELECT ROUND (totalSeconds / (24 * 60 * 60), 1) TotalTimeSpendIn_DAYS,
  ROUND (totalSeconds      / (60 * 60), 0) TotalTimeSpendIn_HOURS,
  ROUND (totalSeconds      / 60) TotalTimeSpendIn_MINUTES,
  ROUND (totalSeconds) TotalTimeSpendIn_SECONDS
FROM
  (SELECT ROUND ( EXTRACT (DAY FROM timeDiff) * 24 * 60 * 60 + EXTRACT (HOUR FROM timeDiff) * 60 * 60 + EXTRACT (MINUTE FROM timeDiff) * 60 + EXTRACT (SECOND FROM timeDiff)) totalSeconds
  FROM
    (SELECT TO_TIMESTAMP(TO_CHAR( date2 , 'yyyy-mm-dd HH24:mi:ss'), 'yyyy-mm-dd HH24:mi:ss') - TO_TIMESTAMP(TO_CHAR(date1, 'yyyy-mm-dd HH24:mi:ss'),'yyyy-mm-dd HH24:mi:ss') timeDiff
    FROM TABLENAME
    )
);
0
Sanjay Tiwari

Biçimler arasında doğru bir şekilde yazılan zaman damgası, alanların yanlış yorumlanması ihtimali vardır.

İşte TableXYZ tablosundan iki farklı tarih (Tarih2, Tarih1) dikkate alındığında doğru olan bir çalışma örneği. 

SELECT ROUND (totalSeconds / (24 * 60 * 60), 1) TotalTimeSpendIn_DAYS,
       ROUND (totalSeconds / (60 * 60), 0) TotalTimeSpendIn_HOURS,
       ROUND (totalSeconds / 60) TotalTimeSpendIn_MINUTES,
       ROUND (totalSeconds) TotalTimeSpendIn_SECONDS
  FROM (SELECT ROUND (
                    EXTRACT (DAY FROM timeDiff) * 24 * 60 * 60
                  + EXTRACT (HOUR FROM timeDiff) * 60 * 60
                  + EXTRACT (MINUTE FROM timeDiff) * 60
                  + EXTRACT (SECOND FROM timeDiff))
                  totalSeconds,
          FROM (SELECT TO_TIMESTAMP (
                            TO_CHAR (Date2,
                                     'yyyy-mm-dd HH24:mi:ss')
                          - 'yyyy-mm-dd HH24:mi:ss'),
                       TO_TIMESTAMP (
                          TO_CHAR (Date1,
                                   'yyyy-mm-dd HH24:mi:ss'),
                          'yyyy-mm-dd HH24:mi:ss')
                          timeDiff
                  FROM TableXYZ))
0
Sreesankar