2016-08-18 3 views
0

Ich berechne Rückübernahmequoten von Patienten und muss herausfinden, was Patienten innerhalb eines bestimmten Intervalls und wie oft wieder aufgenommen haben. Ich habe Daten zu, der wie folgt aussieht:Wie finden Sie Datumsintervalle über mehrere Zeilen hinweg, wenn mehr als zwei Zeilen vorhanden sind?

Subscriber_id New_Admission_date 
01    2016-06-02 
02    2016-06-01 
03    2016-06-10 
04    2016-06-08 
02    2016-06-04 
02    2016-06-30 
03    2016-06-28 

Um herauszufinden, was Patienten innerhalb von 14 Tagen wieder zugelassen haben und was das Intervall zwischen zugibt war, ich habe diesen Code:

select ra.Subscriber_id, DATEDIFF(d,ra.first_ad,ra.last_ad) as interval 
from 
(
    select j.Subscriber_ID, 
    min(j.New_admission_date) as first_ad, 
    max (j.New_Admission_Date) as last_ad 
    from June_inpatients as j 
    inner join 
     (select j.Subscriber_ID, count(Subscriber_ID) as total 
     from June_inpatients as j 
     group by Subscriber_ID 
     having count(Subscriber_ID) >1) as r 
    on j.Subscriber_ID = r.Subscriber_ID 
    group by j.Subscriber_ID 
) as ra 
where DATEDIFF(d,ra.first_ad,ra.last_ad) < 15 

Das Problem ist, dass einige Patienten , wie Patienten ID 02 in den Beispieldaten, haben mehr als 2 bekannt. Mein Code vermisst alle Zwischenmitteilungen, da er min() und max() verwendet. Wie würde ich den Abstand zwischen der ersten Aufnahme und der zweiten Aufnahme eines Patienten finden, wenn drei bekannt sind, und dann den Abstand zwischen der zweiten Aufnahme und der dritten finden?

+0

Welche Version von SQL Server verwenden Sie? Was ist die erwartete Ausgabe Ihres Beispiels? –

Antwort

2

Sie verwenden mindestens SQL 2012 Vorausgesetzt, dass Sie die Lag-Funktion verwenden können.

Die Idee mit LAG/LEAD ist, dass wir Daten aus den vorherigen/nächsten Zeilen abfragen können.

In meinem vollständigen Beispiel verwende ich LAG zweimal, einmal auf Abonnent und einmal auf das Datum. Die Bestellung durch den Abonnenten und das Datum garantieren, dass die vorherigen/nächsten Zeilen in der richtigen Reihenfolge sind. Ich beschränke dann meine where-Klausel, um sicherzustellen:

  1. , dass die vorherige Zeile für den gleichen Teilnehmer ist
  2. , dass die Termine sind innerhalb von 15 Tagen

DECLARE @tbl TABLE (
pkey INT NOT NULL PRIMARY KEY IDENTITY, 
subscriber INT NOT NULL, 
dt DATETIME NOT NULL 
); 

INSERT INTO @tbl 
     (subscriber, dt) 
VALUES 
(1, '2016-06-02'), 
(2, '2016-06-01'), 
(3, '2016-06-10'), 
(4, '2016-06-08'), 
(2, '2016-06-04'), 
(2, '2016-06-30'), 
(3, '2016-06-28'); 

SELECT * 
FROM @tbl 
ORDER BY subscriber, dt 

; WITH tmp AS (
SELECT subscriber, dt, 
LAG(subscriber) OVER (ORDER BY subscriber, dt) previousSubscriber, 
LAG(dt) OVER (ORDER BY subscriber, dt) previousDt 
FROM @tbl 
--ORDER BY subscriber, dt 
) 
SELECT tmp.*, DATEDIFF(DAY, previousDt, dt) 
FROM tmp 
WHERE tmp.subscriber = previousSubscriber 
    AND DATEDIFF(DAY, previousDt, dt) < 15 
+1

Statt einer zweiten 'LAG' für Teilnehmer, sollten Sie besser' PARTITION BY subscriber' verwenden, siehe @CodeDifferents Antwort – dnoeth

1

Wenn Sie SQL Server 2012 oder höher verwenden, versuchen Sie dies:

;WITH 
    cte As 
    (
     SELECT  Subscriber_id, 
        LAG(New_Admission_Date, 1) OVER (PARTITION BY Subscriber_id ORDER BY New_Admission_Date) AS PreviousAdmissionDate, 
        New_Admission_Date 
     FROM  AdmissionTable 
    ) 

SELECT  * 
FROM  cte 
WHERE  DATEDIFF(DAY, PreviousAdmissionDate, New_Admission_Date) <= 14 
1

Dies funktioniert ohne Verzögerungsfunktion.

;WITH J 
AS 
(
    SELECT ROW_NUMBER() OVER(PARTITION BY J1.Subscriber_id ORDER BY J1.New_Admission_date) ROW_ID ,* 
    FROM June_inpatients J1 
) 
SELECT J1.Subscriber_id, J1.New_Admission_date Previous_Admission_date , 
     J2.Subscriber_id, J2.New_Admission_date , DATEDIFF(DD,J1.New_Admission_date,J2.New_Admission_date) Interval 
FROM J J1 
INNER JOIN J J2 ON J1.Subscriber_id = J2.Subscriber_id AND J1.ROW_ID = J2.ROW_ID -1 
WHERE DATEDIFF(DD,J1.New_Admission_date,J2.New_Admission_date)<15 
Verwandte Themen