38

timestamps戻り値を減算する場合はintervalデータ型です。この値を間隔の合計 (ミリ/マイクロ) 秒、つまり整数に変換するエレガントな方法はありますか。

以下は機能しますが、あまりきれいではありません。

select abs( extract( second from interval_difference ) 
          + extract( minute from interval_difference ) * 60 
          + extract( hour from interval_difference ) * 60 * 60 
          + extract( day from interval_difference ) * 60 * 60 * 24
            )
  from ( select systimestamp - (systimestamp - 1) as interval_difference
           from dual )

SQL または PL/SQL でより洗練された方法はありますか?

4

9 に答える 9

26

これが役立つことを願っています:

zep@dev> select interval_difference
      2        ,sysdate + (interval_difference * 86400) - sysdate as fract_sec_difference
      3  from   (select systimestamp - (systimestamp - 1) as interval_difference
      4          from   dual)
      5 ;

INTERVAL_DIFFERENCE                                                             FRACT_SEC_DIFFERENCE
------------------------------------------------------------------------------- --------------------
+000000001 00:00:00.375000                                                                 86400,375

あなたのテストで:

zep@dev> select interval_difference
      2        ,abs(extract(second from interval_difference) +
      3        extract(minute from interval_difference) * 60 +
      4        extract(hour from interval_difference) * 60 * 60 +
      5        extract(day from interval_difference) * 60 * 60 * 24) as your_sec_difference
      6        ,sysdate + (interval_difference * 86400) - sysdate as fract_sec_difference
      7        ,round(sysdate + (interval_difference * 86400) - sysdate) as sec_difference
      8        ,round((sysdate + (interval_difference * 86400) - sysdate) * 1000) as millisec_difference
      9  from   (select systimestamp - (systimestamp - 1) as interval_difference
     10          from   dual)
     11  /

INTERVAL_DIFFERENCE                                                             YOUR_SEC_DIFFERENCE FRACT_SEC_DIFFERENCE SEC_DIFFERENCE MILLISEC_DIFFERENCE
------------------------------------------------------------------------------- ------------------- -------------------- -------------- -------------------
+000000001 00:00:00.515000                                                                86400,515            86400,515          86401            86400515

zep@dev> 
于 2012-04-11T06:40:53.853 に答える
4

残念ながら、pl/sql の間隔型から合計秒数を計算する別の (またはより洗練された) 方法はないと思います。この記事が言及しているように:

... unlike .NET, Oracle provides no simple equivalent to TimeSpan.TotalSeconds.

したがって、間隔から日、時間などを抽出し、それらに対応する値を掛けることが唯一の方法のようです。

于 2012-04-10T15:58:28.810 に答える
3

zep's answerに基づいて、便宜上、関数にまとめました。

CREATE OR REPLACE FUNCTION intervalToSeconds( 
     pMinuend TIMESTAMP , pSubtrahend TIMESTAMP ) RETURN NUMBER IS

vDifference INTERVAL DAY TO SECOND ; 

vSeconds NUMBER ;

BEGIN 

vDifference := pMinuend - pSubtrahend ;

SELECT EXTRACT( DAY    FROM vDifference ) * 86400
     + EXTRACT( HOUR   FROM vDifference ) *  3600
     + EXTRACT( MINUTE FROM vDifference ) *    60
     + EXTRACT( SECOND FROM vDifference )
  INTO
    vSeconds 
  FROM DUAL ;

  RETURN vSeconds ;

END intervalToSeconds ; 
于 2013-07-03T17:00:57.590 に答える
1

@Zhaoping Luの回答に似ていますが、日数から秒を取得するのではなく、秒を直接抽出します。

SELECT extract(second from (end_date - start_date)) as "Seconds number"
FROM my_table

(PostgresSQL 9.6.1 で作業)

于 2019-09-23T12:06:38.813 に答える
0

タイムスタンプをナノ秒に変換する短い方法。

SELECT (EXTRACT(DAY FROM (
    SYSTIMESTAMP --Replace line with desired timestamp --Maximum value: TIMESTAMP '3871-04-29 10:39:59.999999999 UTC'
- TIMESTAMP '1970-01-01 00:00:00 UTC') * 24 * 60) * 60 + EXTRACT(SECOND FROM
    SYSTIMESTAMP --Replace line with desired timestamp
)) *  1000000000 AS NANOS FROM DUAL;

NANOS
1598434427263027000

ナノ秒をタイムスタンプに変換するメソッド。

SELECT TIMESTAMP '1970-01-01 00:00:00 UTC' + numtodsinterval(
    1598434427263027000 --Replace line with desired nanoseconds
/ 1000000000, 'SECOND') AS TIMESTAMP FROM dual;

TIMESTAMP
26/08/20 09:33:47,263027000 UTC

予想どおり、上記のメソッドの結果はタイム ゾーンの影響を受けません。

間隔をナノ秒に変換する短い方法。

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
))) * 1000000000 AS NANOS FROM DUAL;

NANOS
1598434427263027000

ナノ秒を間隔に変換するメソッド。

SELECT numtodsinterval(
    1598434427263027000 --Replace line with desired nanoseconds
/ 1000000000, 'SECOND') AS INTERVAL FROM dual;

INTERVAL
+18500 09:33:47.263027

たとえば、ナノ秒ではなくミリ秒で作業したい場合は、1000000000 を 1000 に置き換えます。

投稿されたメソッドのいくつかを試しましたが、間隔を 86400 で乗算すると「ORA-01873: 間隔の先頭の精度が小さすぎます」という例外が発生したため、機能するメソッドを投稿することにしました。

于 2020-08-26T11:44:14.963 に答える