65

Oracleの2つのタイムスタンプ間の時間差をミリ秒単位で計算するにはどうすればよいですか?

4

11 に答える 11

92

タイプの2つの変数を減算すると、プラットフォームに応じてミリ秒またはマイクロ秒、あるいはその両方を含むTIMESTAMPが得られます。INTERVAL DAY TO SECONDデータベースがWindowsで実行されている場合、systimestamp通常はミリ秒になります。データベースがUnixで実行されている場合、systimestamp通常はマイクロ秒になります。

  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

このEXTRACT関数を使用して、の個々の要素を抽出できます。INTERVAL DAY TO SECOND

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

次に、これらの各コンポーネントをミリ秒に変換して合計します。

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

ただし、通常は、2つの値INTERVAL DAY TO SECONDの間の合計ミリ秒数を計算するよりも、表現を使用するか、時間、分、秒などの列を個別に設定する方が便利です。TIMESTAMP

于 2012-07-23T18:58:24.710 に答える
34

これを行うためのストアドプロシージャは次のとおりです。

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;
/

あなたが彼の仕事を否定したOracle開発者のがらくたを打ち負かしたいのなら、投票してください!

タイムスタンプを初めて比較するのは、全員が1時間ほどかかるはずだからです...

于 2015-11-16T20:02:53.847 に答える
20

より簡単な解決策:

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

タイムスタンプの場合:

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;
于 2012-07-23T18:08:25.450 に答える
9
Select date1 - (date2 - 1) * 24 * 60 *60 * 1000 from Table;
于 2012-07-23T18:08:35.157 に答える
3

これが徹底的に答えられたことは知っていますが、私は自分の機能をみんなと共有したいと思いました。回答を日、時間、分、秒、またはミリ秒のいずれにするかを選択できます。ニーズに合わせて変更できます。

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;

たとえば、Return_Elapsed_Time(TO_TIMESTAMP('12 .04.2017 12:00:00.00'、' DD.MM.YYYY HH24:MI:SS.FF ' )、SYSTIMESTAMP)、次のようなものを返す必要があります。

47344620000 milliseconds
于 2018-10-12T16:19:17.990 に答える
1

次のような手順を使用することをお勧めします。

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;

次の電話で確認できます。

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;
于 2017-04-12T14:05:24.133 に答える
1

私は多くの人がこの解決策を単純明快だと思っていることを知っています:

create table diff_timestamp (
f1 timestamp
, f2 timestamp);

insert into diff_timestamp values(systimestamp-1, systimestamp+2);
commit;

select cast(f2 as date) - cast(f1 as date) from diff_timestamp;

ビンゴ!

于 2020-10-07T07:03:59.027 に答える
0

フォーマット間でタイムスタンプが正しくキャストされていないと、フィールドが誤って解釈される可能性があります。

これは、テーブルTableXYZから2つの異なる日付(Date2、Date1)が考慮された場合に正しい作業サンプルです。

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))
于 2014-08-14T00:39:35.300 に答える
0

上記のものには構文エラーがあります。Oracleで以下を使用してください。

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
    )
);
于 2014-12-01T22:04:15.237 に答える
0

I)2つのタイムスタンプ列間の経過時間を秒単位で計算する必要がある場合は、次のことを試してください。

SELECT 
    extract ( day from (end_timestamp - start_timestamp) )*86400 
    + extract ( hour from (end_timestamp - start_timestamp) )*3600 
    + extract ( minute from (end_timestamp - start_timestamp) )*60 
    + extract ( second from (end_timestamp - start_timestamp) ) 
FROM table_name

II)文字形式で時差を表示したい場合は、次のことを試してください。

SELECT to_char (end_timestamp - start_timestamp) FROM table_name
于 2017-10-26T08:57:08.307 に答える
0

間隔をナノ秒に、ナノ秒を間隔に変換するいくつかの方法をここに投稿しました。これらの方法の精度はナノ秒です。

ナノ秒ではなくミリ秒になるように調整する必要があります。

間隔をナノ秒に変換するためのより短い方法。

SELECT (EXTRACT(DAY FROM (
    INTERVAL '+18500 09:33:47.263027' DAY(5) TO SECOND --Replace line with desired interval --Maximum value: INTERVAL '+694444 10:39:59.999999999' DAY(6) TO SECOND(9) or up to 3871 year
) * 24 * 60) * 60 + EXTRACT(SECOND FROM (
    INTERVAL '+18500 09:33:47.263027' DAY(5) TO SECOND --Replace line with desired interval
))) * 100 AS MILLIS FROM DUAL;

MILLIS
1598434427263.027
于 2020-08-26T13:35:25.483 に答える