web-dev-qa-db-ja.com

Oracle SQLで2つの日付間の経過時間を見つける

hh:mm:ssの形式で時刻の差を見つける必要があります

select msglog.id,max(msglog.timestamp) enddate,
   min(msglog.timestamp) startdate,
   enddate - startdate
   from MESSAGELOG msglog
   group by id

上記のクエリでは、msglog.timestampはDATEタイプです。

Oracleの正しい形式で経過時間または時間の差を取得するにはどうすればよいですか?

9
suni

enddate - startdateのような2つのDATE値を減算すると、小数の精度で日数の差が得られます。たとえば、1.5は1 1/2日または36時間を意味します。多くの数学を使用してHH:MI:SSに変換できますが、より簡単な方法は、 NUMTODSINTERVAL 関数を使用して10進値をINTERVAL DAY TO SECOND値に変換することです:

  NUMTODSINTERVAL(enddate - startdate, 'DAY')

TO_CHAR関数は、これをHH:MI:SSとしてフォーマットできると思いますが、そのように機能していないようです。代わりにEXTRACTを使用し、TO_CHARを使用して先行ゼロを取得できます。

 TO_CHAR(EXTRACT(HOUR FROM NUMTODSINTERVAL(enddate-startdate, 'DAY')), 'FM00')
   || ':' ||
 TO_CHAR(EXTRACT(MINUTE FROM NUMTODSINTERVAL(enddate-startdate, 'DAY')), 'FM00')
   || ':' ||
 TO_CHAR(EXTRACT(SECOND FROM NUMTODSINTERVAL(enddate-startdate, 'DAY')), 'FM00')

書式コードの00の部分は2桁を指定し、必要に応じて先頭にゼロを付けます。 FM部分は、フォーマットされた結果の先行スペースを取り除きます。これは、必要に応じて負の符号用に予約されています。

また、クエリは集計値を取得し、それらを同じSELECTリストで使用することにも注意してください。 Oracleはこれを許可しません。代わりに次のようなものを試してください:

WITH StartEndByID AS (
  SELECT
    msglog.id,
    NUMTODSINTERVAL(max(msglog.timestamp) - min(msglog.timestamp), 'DAY') elapsed
  FROM messagelog msglog
  GROUP BY id
)
SELECT
  id,
  TO_CHAR(EXTRACT(HOUR FROM elapsed), 'FM00') || ':' ||
    TO_CHAR(EXTRACT(MINUTE FROM elapsed), 'FM00') || ':' ||
    TO_CHAR(EXTRACT(SECOND FROM elapsed), 'FM00') AS ElapsedHHMISS
FROM StartEndByID
20
Ed Gibbs

Oracleの日付演算では、日数で表された数値になります。したがって、時間に変換するには、24を掛けてからtruncで整数を取得します。

_trunc(24 * (enddate - startdate))
_

分を取得するには、daysの値を分に変換し、mod()を60に変換します。

_mod(trunc(24 * 60 * (enddate - startdate)), 60)
_

秒の場合も、日数を秒に変換し、mod()を60に変換します。

_mod(trunc(24 * 60 * 60 * (enddate - startdate)), 60)
_

これらを組み合わせて、必要な文字列値を取得できます。

17
GriffeyDog

秒単位で差分を取得するには、これを使用できます

select round(24 * 60 * 60* (TO_DATE('2017/02/17 9:32:25', 'YYYY/MM/DD HH:MI:SS') - TO_DATE('2017/02/17 8:30:30', 'YYYY/MM/DD HH:MI:SS'))) from dual;
2
ok2307