2016-07-20 6 views
0

Ich habe eine Tabelle, die Datensätze in 5-Minuten-Schritten hat, die wie folgt aussieht:Markieren Sie eine Zeile in jeder Zeile

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 

ich von so auswählen muß das wäre Erstellen Sie ein Ergebnis für jede Minute bis zu der Zeit in der nächsten Zeile von jetzt bis zu den letzten 5 Stunden. Zum Beispiel:

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 
... 

Ich fühle mich wie ich „CONNECT BY“ aber ich kann nicht scheinen, um herauszufinden, wie es zu sagen, zu verwenden, den Zeitstempel von einer Zeile als Start und der nächste Zeile als Ende verwenden kann jedes Mal.

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

Wenn die bestehenden Zeilen in der Tat sind, wie Sie gesagt haben, fünf Minuten auseinander, warum müssen Sie mit der nächsten Zeile vergleichen? Oder sind sie nicht wirklich genau fünf Minuten auseinander, jedes Mal? – mathguy

+0

@mathguy Sie sind genau 5 Minuten auseinander, ich glaube, ich habe nicht darüber nachgedacht, die Reihe nicht wirklich in Betracht zu ziehen. Ich könnte mir einfach eine Zeit nehmen und jedes Mal 4 Minuten hinzufügen. – jrandomuser

+0

Dann ist die Lösung viel einfacher, ich habe es meiner Antwort hinzugefügt. – mathguy

Antwort

2

So etwas sollte funktionieren. Beachten Sie die Verwendung der analytischen Funktion lead(), um die "nächste" Zeit zu identifizieren. Sie sollten es nicht brauchen (und Sie würden dann keine separate Unterabfrage benötigen), wenn die Intervalle tatsächlich genau fünf Minuten wären, da Sie in diesem Fall einfach level <= 5 sagen könnten. Außerdem änderte ich den Spaltennamen von timestamp zu timestp - mit reservierten Oracle-Schlüsselwörtern, da Spaltennamen nach Ärger fragen.

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 

ergänzt: Die OP stellte klar, dass die Intervalle immer genau fünf Minuten auseinander. So ist die Lösung ist viel einfacher:

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 
; 

Ein Unterschied gegenüber der ersten Lösung: In dieser (zweiten, einfacheren) Lösung, zusätzliche Zeilen werden auch für die „letzte“ Zeile in der ursprünglichen Tabelle hinzugefügt werden. Es ist nicht wirklich klar, was die Anforderung für die letzte Zeile ist, ob diese zusätzlichen Zeilen benötigt werden oder nicht.

+0

Dies ist eine brilliante Lösung, die mich ein wenig Zeit gekostet hat, um meinen Kopf herumzukommen. Ich habe es in beide Richtungen implementiert, nur um es zu verstehen. Ich habe einen zusätzlichen Grund gefunden, mit Level <= 5 statt Level <= (next_timestp - timestp) * (24 * 60) zu gehen. Wenn Sie sich auf den nächsten Zeitstempel-Datensatz verlassen, können Sie die letzten Ergebnisse erst nach 5 Minuten abrufen, da kein Datensatz für den Vergleich vorhanden ist. Mit <= 5 erhalten Sie immer die neuesten Ergebnisse. – jrandomuser