2017-11-15 1 views
3

Ich bin mit einer Oracle-Datenbank und ich habe eine Tabelle, die zwei Spalten mit Daten wie so hat:Oracle wählen Daten von zusammenhängenden Datum Blöcke

HASH | DATE 
----------------- 
abcd | 2017-11-01 
abcd | 2017-11-02 
abcd | 2017-11-03 
wxyz | 2017-11-04 
wxyz | 2017-11-05 
abcd | 2017-11-06 
wxyz | 2017-11-07 
abcd | 2017-11-08 
abcd | 2017-11-09 
lmno | 2017-11-10 
lmno | 2017-11-11 

Ich möchte die Fenster von Zeit wissen, dass jeder Hash zu sehen ist . So wie

hash | start  | end 
------------------------------ 
abcd | 2017-11-01 | 2017-11-03 
wxyz | 2017-11-04 | 2017-11-05 
abcd | 2017-11-06 | 2017-11-06 
wxyz | 2017-11-07 | 2017-11-07 
abcd | 2017-11-08 | 2017-11-09 
lmno | 2017-11-10 | 2017-11-11 

Was ich bisher habe, ist im Grunde diese:

SELECT HASH, MIN(DATE) ST, MAX(DATE) ED 
FROM HASH_TABLE 
GROUP BY HASH 
ORDER BY 3 DESC 

Und das fast funktioniert, aber es gibt mir wie „ABCD“ als Start von 2017.11.01 und ein Ende vom 2017-11-09 das "versteckt" die Tatsache, dass es in der Mitte geschaltet hat.

Gibt es eine Möglichkeit, diese Ergebnisse durch zusammenhängende Datum/Zeit "Blöcke" zu gruppieren?

Antwort

1

Es sieht aus wie "Lücken und Inseln" Problem:

WITH cte("hash","date") AS (
    SELECT 'abcd', DATE'2017-11-01' FROM dual UNION ALL 
    SELECT 'abcd', DATE'2017-11-02' FROM dual UNION ALL 
    SELECT 'abcd', DATE'2017-11-03' FROM dual UNION ALL 
    SELECT 'wxyz', DATE'2017-11-04' FROM dual UNION ALL 
    SELECT 'wxyz', DATE'2017-11-05' FROM dual UNION ALL 
    SELECT 'abcd', DATE'2017-11-06' FROM dual UNION ALL 
    SELECT 'wxyz', DATE'2017-11-07' FROM dual UNION ALL 
    SELECT 'abcd', DATE'2017-11-08' FROM dual UNION ALL 
    SELECT 'abcd', DATE'2017-11-09' FROM dual UNION ALL 
    SELECT 'lmno', DATE'2017-11-10' FROM dual UNION ALL 
    SELECT 'lmno', DATE'2017-11-11' FROM dual 
) 
select "hash" 
     ,min("date") as startdate 
     ,max("date") as enddate 
from (
    select "date","hash" 
     , row_number() over (order by "date") 
     - row_number() over (partition by "hash" order by "date") as grp 
    from cte 
) A 
group by "hash", grp 
ORDER BY startdate; 

DBFiddle Demo

+0

Dies sieht aus wie es im Grunde richtig ist. Sie müssen die ganze Sache in eine Auswahl * von (...) Reihenfolge von Startdatum wickeln, um die Ergebnisse korrekt zu ordnen, aber ansonsten scheint es zu funktionieren. – MichaelB

0

ab hash_table

hash varchar2(4)
date_ date

select hash, min(date_) start_, max(date_) end_ 
    from 
    (
    select h.hash, h.date_, row_number() over (partition by hash order by date_) rn 
     from hash_table h 
    ) 
    group by hash, date_ - rn 
    order by 2; 
+0

Dies verliert alle "abcd" in der Mitte. – MichaelB

+0

@MichaelB ja, du hast Recht. Also, ich habe meine Antwort bearbeitet. –

+0

Cool, aber jetzt scheint es, alle Datensätze anstelle der Gruppen auszuwählen – MichaelB