SQL: Bereiche einer bestimmten Größe finden

Aus DBWiki
Wechseln zu: Navigation, Suche

Zurück zur Übersicht



Ausgangsbasis für dieses Beispiel sollen wieder die Daten aus Aufeinanderfolgende Bereiche in einer Sequenz erkennen sein. Anders als in Ober- und Untergrenzen aufeinanderfolgender Bereiche ausgeben, ist das Ende des Bereichs durch eine feste Größe vorgegeben. Daraus ergibt sich dann die Bedingung, dass die Differenz aus p1.id und p0.id gleich der Bereichsgröße minus 1 sein muss.


Es sollen z.B. alle angrenzenden gute Produkte gefunden werden, um sie paarweise zu verpacken. Bei Überschneidungen (das wäre ein anderes Thema) muss eine manuelle Auswahl für die Verpackung getroffen werden.

Allgemeine Lösung

SELECT p0.id AS anfang, p1.id AS ende
FROM   vw_produktion AS p0,
       vw_produktion AS p1
WHERE  p0.id < p1.id AND
       p1.id - p0.id = 1 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 )

Lösung mittels Window Funktion

Mit der lead()-Funktion kann man den nächsten Wert einer zuvor ermittelten Gruppe bestimmen, der Null ist, falls kein solcher Wert existiert. Damit lässt sich dann ein Ausschlußkriterium definieren.

WITH w0 AS (
    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 ),
     w1 AS (
    SELECT id,
           lead( id ) OVER ( PARTITION BY grp ORDER BY id ) AS ende
    FROM   w0
    WHERE  druck BETWEEN 1.28 AND 1.44 )
SELECT id AS anfang,
       ende
FROM   w1
WHERE  ende IS NOT NULL

Die Lösung ist in diesem DBFiddle umgesetzt.

anfang ende
1 2
10 11
11 12



Zurück zur Übersicht