Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Gruppieren Sie Zeilen, die weniger als 15 Tage voneinander entfernt sind, und weisen Sie ein Mindest-/Höchstdatum zu

Wie in den Kommentaren erwähnt, könnten Sie die LAG verwenden Funktion dazu. Die Grundidee besteht darin, jeder Zeile einen 0/1-Wert zuzuweisen:Wenn sie innerhalb von 15 Tagen nach der vorherigen Zeile liegt, dann 0, sonst 1. Dann verwenden Sie SUM() OVER () um die 1s und 0s in Zahlen umzuwandeln, die zum Gruppieren verwendet werden könnten.

Beachten Sie, dass dies viel längere Datumsbereiche zusammenfassen könnte, z. 01-01 , 01-11 , 01-21 , 02-01 und 02-11 werden zusammen gruppiert, obwohl das erste und das letzte Datum mehr als 15 Tage auseinander liegen.

DECLARE @T TABLE (HASTA_ID INT, PROTOKOL_ID INT, STARTDATE DATE, ENDDATE DATE);
INSERT INTO @T VALUES
(273065, 11, '2018-01-24', '2018-01-30'),
(273065, 12, '2018-01-25', '2018-02-10'),
(273065, 13, '2018-01-30', '2018-01-30'),
(273065, 14, '2018-02-23', '2018-02-28'),
(273065, 15, '2018-03-21', '2018-03-29'),
(273065, 16, '2018-05-03', '2018-05-04'),
(273065, 17, '2018-05-03', '2018-05-08'),
(273065, 18, '2018-05-14', '2018-05-22'),
(273065, 19, '2018-05-22', '2018-05-23'),
(273065, 20, '2018-09-20', '2018-09-30');

WITH CTE1 AS (
    SELECT *, CASE WHEN LAG(STARTDATE) OVER (PARTITION BY HASTA_ID ORDER BY STARTDATE) >= DATEADD(DAY, -14, STARTDATE) THEN 0 ELSE 1 END AS CHG
    FROM @T
), CTE2 AS (
    SELECT *, SUM(CHG) OVER (PARTITION BY HASTA_ID ORDER BY STARTDATE) AS GRP
    FROM CTE1
)
SELECT *,
    MIN(STARTDATE) OVER (PARTITION BY HASTA_ID, GRP) AS EX_STARTDATE,
    MAX(ENDDATE) OVER (PARTITION BY HASTA_ID, GRP) AS EX_ENDDATE
FROM CTE2
ORDER BY HASTA_ID, STARTDATE

Demo auf DB Fiddle