SQL: Ober- und Untergrenzen aufeinanderfolgender Bereiche ausgeben

Aus DBWiki
Wechseln zu: Navigation, Suche

Zurück zur Übersicht



Die Problemstellung und die Ausgangsdaten für das Beispiel sollen die gleichen wie in Aufeinanderfolgende Bereiche in einer Sequenz erkennen sein - jedoch mit dem Unterschied, dass im Ergebnis jeweils der Anfang und das Ende des Bereichs auszugegeben ist.

Allgemeine Lösung

Durch die Bedingung, dass die id in p0 kleiner sein muss als die in p1 stellen wird die erste Randbedingung auf. Weiterhin muss gelten, dass weder kein Datensatz zwischen p0.id und p1.id existiert, dessen druck außerhalb des Wertebereichs liegt oder eine id vorhanden ist, die um 1 kleiner als die p0.id ist und in den Wertebereich passt oder eine id vorhanden ist, die um 1 größer als die p1.id ist und in den Wertebereich passt.

SELECT p0.id AS anfang,
       p1.id AS ende
FROM   vw_produktion AS p0,
       vw_produktion AS p1
WHERE  p0.id < p1.id AND
       NOT EXISTS( SELECT 0
                   FROM   vw_produktion AS p2 
                   WHERE  ( ( p2.druck < 1.28 OR p2.druck > 1.44 ) AND 
                            p2.id BETWEEN p0.id AND p1.id ) OR
                          ( p2.id = p0.id - 1 AND p2.druck BETWEEN 1.28 AND 1.44 ) OR
                          ( p2.id = p1.id + 1 AND p2.druck BETWEEN 1.28 AND 1.44 ) )

Lösung mittels Window-Funktion

SELECT MIN( id ) AS anfang,
       MAX( id ) AS ende
FROM   ( SELECT *,
                ROW_NUMBER() OVER ( ORDER BY id )
              - ROW_NUMBER() OVER ( PARTITION BY CASE WHEN druck BETWEEN 1.28 AND 1.44 THEN 1 END
                                    ORDER BY id ) AS grp
             FROM   vw_produktion ) AS p
WHERE  druck BETWEEN 1.28 AND 1.44
GROUP  BY grp
HAVING COUNT( * ) >= 2
ORDER  BY 1

Die Lösung ist in diesem DBFiddle umgesetzt.

anfang ende
1 2
10 12



Zurück zur Übersicht