2016-07-20 4 views
0

を日付値の間の各分の行を選択します。私は次のような5分単位でレコードを持つテーブル持って各行の

UDSNSI  TIMESTAMP 
-8134  7/20/2016 4:30:00 AM 
-8125  7/20/2016 4:35:00 AM 
-8098  7/20/2016 4:40:00 AM 

私はそれだろうように中から選択する必要がありますが次の行の時刻から過去5時間までの毎分の結果を作成します。たとえば:

UDSNSI  TIMESTAMP 

-8134  7/20/2016 4:30:00 AM 
-8134  7/20/2016 4:31:00 AM 
-8134  7/20/2016 4:32:00 AM 
-8134  7/20/2016 4:33:00 AM 
-8134  7/20/2016 4:34:00 AM 
-8125  7/20/2016 4:35:00 AM 
-8125  7/20/2016 4:36:00 AM 
-8125  7/20/2016 4:37:00 AM 
... 

私は「CONNECT BY」を使用することができるような気がしますが、私はエンドとしてスタートし、次の行として1行からTIMESTAMPを使用するよう指示する方法を見つけ出すように見えることはできません毎回。

select udsnsi, 
     timestamp 
from plan 
where timestamp <sysdate and timestamp >= sysdate - 5/24 

connect by timestamp <= 
(
    select .... timestamp from row X and row X + 1 
       and create a row for every minute value in between 
       using X's udsnsi value 
) 
+0

実際にあなたが言ったように既存の行が5分離れている場合、なぜ次の行と比較する必要がありますか?それとも、まったく違うのですか? – mathguy

+0

@mathguy彼らはちょうど5分離れている、私は本当に行を考慮する必要はないと思うと思う。私はちょうど時間をかけて、毎回4分を追加することができます。 – jrandomuser

+0

それから、ソリューションははるかに簡単です、私はそれを私の答えに加えました。 – mathguy

答えて

2

何かこれはうまくいくはずです。分析関数lead()を使用して、「次の」時間を識別することに注意してください。間隔が実際にはちょうど5分の場合は、それを必要としないでください(別のサブクエリは必要ありません)。その場合、単にlevel <= 5と言うことができます。また、列名をtimestampからtimestpに変更しました。予約されたOracleキーワードを列名として使用するとトラブルが発生します。

with 
    plan ( udsnsi, timestp) as (
     select '-8134', to_date('7/20/2016 4:30:00 PM', 'mm/dd/yyyy hh:mi:ss AM') 
                     from dual union all 
     select '-8125', to_date('7/20/2016 4:35:00 PM', 'mm/dd/yyyy hh:mi:ss AM') 
                     from dual union all 
     select '-8098', to_date('7/20/2016 4:40:00 PM', 'mm/dd/yyyy hh:mi:ss AM') 
                       from dual 
    ), 
    prep ( udsnsi, timestp, next_timestp) as (
     select udsnsi, timestp, lead(timestp) over (order by timestp) 
     from plan 
     where timestp < sysdate and timestp >= sysdate - 5/24 
    ) 
select udsnsi, timestp + (level - 1)/(24 * 60) as timestp 
from prep 
connect by prior udsnsi = udsnsi 
and  prior sys_guid() is not null 
and  level <= (next_timestp - timestp) * (24 * 60) 
order by timestp 
; 

UDSNSI TIMESTP 
------ ---------------------- 
-8134 07/20/2016 04:30:00 PM 
-8134 07/20/2016 04:31:00 PM 
-8134 07/20/2016 04:32:00 PM 
-8134 07/20/2016 04:33:00 PM 
-8134 07/20/2016 04:34:00 PM 
-8125 07/20/2016 04:35:00 PM 
-8125 07/20/2016 04:36:00 PM 
-8125 07/20/2016 04:37:00 PM 
-8125 07/20/2016 04:38:00 PM 
-8125 07/20/2016 04:39:00 PM 
-8098 07/20/2016 04:40:00 PM 

を追加しました:OPは間隔が5分間隔で正確に常にあることを明らかにしました。そう溶液は、はるかに簡単である:最初の溶液対

select udsnsi, timestp + (level - 1)/(24 * 60) as timestp 
from prep 
connect by prior udsnsi = udsnsi 
    and  prior sys_guid() is not null 
    and  level <= 5 
; 

1つの違いは:この(第2、より簡単な)溶液に、追加の行は、元の表の「最後」の行のために追加されるであろう。これらの追加の行が必要であるかどうかにかかわらず、最終行の要件が何であるかは、実際には明確ではありません。

+0

これは私の頭の中で少し時間がかかった素晴らしい解決策です。私は両方の方法で実装したので、わかりました。私はレベル<=(next_timestp - timestp)*(24 * 60)の代わりにレベル<= 5で行く別の理由を見つけました。あなたが次のタイムスタンプレコードに頼っている場合は、5分前までは最新の結果を得ることができません。 <= 5を使用すると、常に最新の結果が得られます。 – jrandomuser

関連する問題