2012-04-10 43 views
21

當減去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更優雅的方法是什麼?

+1

:地方我發現這個' 選擇(TRUNC(SYSDATE)+ out.interv - TRUNC (SYSDATE))* 86400 from(select systimestamp - (systimestamp -1)as interv from dual)out' – 2012-04-10 20:37:34

+0

由於添加了以秒爲單位的時間間隔返回到固定精度數字變量,第二小數部分丟失在評論中提到的查詢 – 2012-04-10 20:40:26

回答

18

我希望這幫助:

[email protected]> 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 

隨着你的測試:

[email protected]> 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 

[email protected]> 
+3

我最終解釋了爲什麼它在這裏工作:http://stackoverflow.com/a/17413839/458741 – Ben 2013-07-03 20:16:59

+1

這不適用於interval_difference的某些值。例如: 選擇interval_difference, SYSDATE +(interval_difference * 86400) - SYSDATE作爲fract_sec_difference 從( 選擇SYSTIMESTAMP - (SYSTIMESTAMP - 1/3)作爲interval_difference 從雙 ); – 2015-07-27 20:56:01

3

不幸的是,我不認爲有一種計算pl/sql中間隔類型總秒數的替代方法(或更優雅的方法)。作爲this article提到:

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

因此提取的間隔日,小時等,並與相應的值乘以似乎是唯一的出路。

2

基於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 ; 
+2

謝謝,但是一個函數的效率遠低於SQL。單獨在SQL/PL/SQL上下文切換中,每個記錄將損失大約1毫秒。也無需從雙選中選擇或將結果分配給變量,您可以直接返回。我會寫這樣的功能:http:// www。sqlfiddle.com/#!4/42d23/1。不過,我想強調的是,如果可能的話,不應該使用函數。 – Ben 2013-07-03 17:12:42

+0

另外,現在我來想想它的代碼是我的...我問是否有更好的方法來做到這一點!歡迎來到Stack Overflow :-)。 – Ben 2013-07-03 17:16:05

6

我已經發現這個工作。顯然,如果你使用時間戳進行運算,它們將被轉換爲某種內部數據類型,當相互減少時,它將把間隔作爲數字返回。

簡單嗎?是。優雅?否。完成工作?哦耶。

SELECT ((A + 0) - (B + 0)) * 24 * 60 * 60 
FROM 
(
    SELECT SYSTIMESTAMP A, 
      SYSTIMESTAMP - INTERVAL '1' MINUTE B 
    FROM DUAL 
); 
+0

這隻給我整秒鐘。 – vikingsteve 2015-02-04 11:35:46

+0

糟糕,真的。這個問題特意要求微/毫秒。不過,這是一個簡單的方法。 – Waldo 2015-02-11 11:19:27

+0

CAST(A AS DATE)相當於(A + 0) – Andrew 2016-04-15 09:58:19

12

一個簡單的方法:

select extract(day from (ts1-ts2)*86400) from dual; 

想法是通過倍86400到間隔值轉換爲天(= 24 * 60 * 60)。 然後提取實際上是我們想要的第二個值的'日'值。

+0

這是一個可愛的答案。 – 2016-10-25 20:16:12

+1

我適應了這個使用'extract(day from(ts1-ts2)* 86400 * 1000)/ 1000'來獲得毫秒精度。 – 2016-12-06 04:55:28

0

選擇(CAST(timestamp1如日期)-cast(timestamp2如日期))* 24 * 60 * 60)

相關問題