5

INTERVALを合計しようとしています。例えば

SELECT SUM(TIMESTAMP1 - TIMESTAMP2) FROM DUAL

Oracle と SQL Server の両方で機能するクエリを作成することは可能ですか? もしそうなら、どのように?

編集:DATEをINTERVALに変更

4

7 に答える 7

6

残念ながら、Oracle と MSSQL の両方で機能するソリューションではうまくいきません。日付演算は、さまざまな種類の DBMS で非常に異なるものです。

とにかく、Oracle では、単純な算術演算で日付を使用できます。そして、数値を DAY TO SECOND INTERVAL に変換する関数 NUMTODSINTERVAL があります。それでは、それらをまとめてみましょう。

日付のペアがおよそ 12 時間離れている 2 つの行の単純なテスト データ:

SQL> alter session set nls_date_format = 'dd-mon-yyyy hh24:mi:ss'
  2  /

Session altered.

SQL> select * from t42
  2  /

D1                   D2
-------------------- --------------------
27-jul-2010 12:10:26 27-jul-2010 00:00:00
28-jul-2010 12:10:39 28-jul-2010 00:00:00

SQL>

経過時間の合計を見つける単純な SQL クエリ:

SQL> select numtodsinterval(sum(d1-d2), 'DAY')
  2  from t42
  3  /

NUMTODSINTERVAL(SUM(D1-D2),'DAY')
-----------------------------------------------------
+000000001 00:21:04.999999999

SQL>

1 日強、これは私たちが期待するものです。


「編集:DATEをINTERVALに変更」

TIMESTAMP 列を操作するのは少し手間がかかりますが、同じ方法で作業できます。

次のサンプルで。T42T は T42 と同じですが、列のデータ型が DATE ではなく TIMESTAMP である点のみが異なります。このクエリは、DS INTERVAL のさまざまなコンポーネントを抽出し、それらを秒に変換します。次に、合計して INTERVAL に変換し直します。

SQL> select numtodsinterval(
  2              sum(
  3                  extract (day from (t1-t2)) * 86400
  4                   + extract (hour from (t1-t2)) * 3600
  5                   + extract (minute from (t1-t2)) * 600
  6                   + extract (second from (t1-t2))
  7            ), 'SECOND')
  8  from t42t
  9  /

NUMTODSINTERVAL(SUM(EXTRACT(DAYFROM(T1-T2))*86400+EXTRACT(HOURFROM(T1-T2))*
---------------------------------------------------------------------------
+000000001 03:21:05.000000000

SQL>

少なくともこの結果は秒単位です!

于 2010-07-28T11:17:30.817 に答える
5

さて、少し地獄の後で、stackoverflowersの答えの助けを借りて、私は自分のニーズに合った解決策を見つけました。


SELECT
  SUM(CAST((DATE1 + 0) - (DATE2 + 0) AS FLOAT) AS SUM_TURNAROUND
FROM MY_BEAUTIFUL_TABLE
GROUP BY YOUR_CHOSEN_COLUMN

これにより、Oracle ant SQL Serverの両方の日数を表すfloat(私にとってはまったく問題ありません)が返されます。

両方の日付にゼロを追加した理由は、私の場合、Oracle DBの日付列がTIMESTAMPタイプであり、SQL Serverの日付列がDATETIMEタイプであるためです(これは明らかに奇妙です)。したがって、OracleのTIMESTAMPにゼロを追加することは、日付をキャストするのと同じように機能し、SQLServerのDATETIMEタイプには影響しません。

君たちありがとう!あなたは本当に役に立ちました。

于 2010-07-28T13:16:41.003 に答える
3

2 つの日時を合計することはできません。意味がありません。つまり、15:00:00 と 23:59:00 を足すとどうなるでしょうか? 翌日のどこか?等

ただし、SQL Server の Dateadd() などの関数を使用して、時間の増分を追加できます。

于 2010-07-28T10:51:12.807 に答える
3

SQL Server では、個々のタイムスパンがすべて 24 時間未満である限り、次のようなことができます

WITH TIMES AS
(
SELECT CAST('01:01:00' AS DATETIME) AS TimeSpan
UNION ALL
SELECT '00:02:00'
UNION ALL
SELECT '23:02:00'
UNION ALL
SELECT '17:02:00'
--UNION ALL SELECT '24:02:00' /*This line would fail!*/
),
SummedTimes As
(
SELECT cast(SUM(CAST(TimeSpan AS FLOAT)) as datetime) AS [Summed] FROM TIMES
)
SELECT 
    FLOOR(CAST(Summed AS FLOAT)) AS D,
    DATEPART(HOUR,[Summed]) AS H,
    DATEPART(MINUTE,[Summed]) AS M,
    DATEPART(SECOND,[Summed]) AS S
FROM SummedTimes

与える

D           H           M           S
----------- ----------- ----------- -----------
1           17          7           0

24 時間を超えるタイムスパンを処理したい場合は、CLR 統合とTimeSpan構造を確認する必要があると思います。携帯性は絶対ダメ!

編集: SQL Server 2008にはDateTimeOffsetデータ型がありますが、これは役立つかもしれませんが、SUMmingまたはfloatにキャストすることはできません

于 2010-07-28T10:56:21.893 に答える
0

これを使用することもできます:

select  
  EXTRACT (DAY FROM call_end_Date - call_start_Date)*86400 + 
  EXTRACT (HOUR FROM call_end_Date - call_start_Date)*3600 + 
  EXTRACT (MINUTE FROM call_end_Date - call_start_Date)*60 + 
  extract (second FROM call_end_Date - call_start_Date) as interval
from table;
于 2013-08-10T20:01:44.613 に答える
0

これもありえないと思います。好みに応じて日付値を計算するカスタム ソリューションを使用します。

于 2010-07-28T10:56:06.840 に答える