0

Ich benutze SQL Server 2008 und versuche, die Geschwindigkeit meiner Abfrage unten zu erhöhen. Die Abfrage weist den Patienten basierend auf Rückübernahmedaten Punkte zu.SQL: CTE-Abfrage Geschwindigkeit

Beispiel: Ein Patient wird am 1/2, 1/5, 1/7, 1/8, 1/9, 2/4 gesehen. Ich möchte zuerst innerhalb von 3 Tagen die Gruppe besuchen. 1/2-5 sind gruppiert, 1/7-9 sind gruppiert. 1/5 ist NICHT mit 1/7 gruppiert, da das tatsächliche Besuchsdatum von 1/5 1/2 ist. 1/7 würde 3 Punkte erhalten, weil es ein Wiederaufnahmewert von 1/2 ist. 2/4 würde auch 3 Punkte erhalten, da es sich um eine Rückmeldung von 1/7 handelt. Wenn die Daten gruppiert sind, ist das erste Datum das tatsächliche Besuchsdatum.

Die meisten Artikel schlagen vor, den Datensatz zu begrenzen oder Indizes hinzuzufügen, um Geschwindigkeit zu erhöhen. Ich habe die Anzahl der Zeilen auf etwa 15.000 begrenzt und einen Index hinzugefügt. Wenn die Abfrage mit 45 Testbesuchsdaten/3 Testpatienten ausgeführt wird, dauert die Abfrage 1,5 Minuten. Mit meinem eigentlichen Datensatz dauert es> 8 Stunden. Wie kann ich diese Abfrage < 1 Stunde ausführen lassen? Gibt es eine bessere Möglichkeit, meine Anfrage zu schreiben? Sieht mein Index korrekt aus? Jede Hilfe würde sehr geschätzt werden.

Beispiel erwartete Ergebnisse unter Abfrage.

;CREATE TABLE RiskReadmits(MRN INT, VisitDate DATE, Category VARCHAR(15)) 
;CREATE CLUSTERED INDEX Risk_Readmits_Index ON RiskReadmits(VisitDate) 

;INSERT RiskReadmits(MRN,VisitDate,CATEGORY) 
VALUES 
(1, '1/2/2016','Inpatient'), 
(1, '1/5/2016','Inpatient'), 
(1, '1/7/2016','Inpatient'), 
(1, '1/8/2016','Inpatient'), 
(1, '1/9/2016','Inpatient'), 
(1, '2/4/2016','Inpatient'), 
(1, '6/2/2016','Inpatient'), 
(1, '6/3/2016','Inpatient'), 
(1, '6/5/2016','Inpatient'), 
(1, '6/6/2016','Inpatient'), 
(1, '6/8/2016','Inpatient'), 
(1, '7/1/2016','Inpatient'), 
(1, '8/1/2016','Inpatient'), 
(1, '8/4/2016','Inpatient'), 
(1, '8/15/2016','Inpatient'), 
(1, '8/18/2016','Inpatient'), 
(1, '8/28/2016','Inpatient'), 
(1, '10/12/2016','Inpatient'), 
(1, '10/15/2016','Inpatient'), 
(1, '11/17/2016','Inpatient'), 
(1, '12/20/2016','Inpatient') 

;WITH a AS (
    SELECT 
      z1.VisitDate 
     , z1.MRN 
     , (SELECT MIN(VisitDate) FROM RiskReadmits WHERE VisitDate > DATEADD(day, 3, z1.VisitDate)) AS NextDay 
    FROM 
     RiskReadmits z1 
    WHERE 
     CATEGORY = 'Inpatient' 
), a1 AS ( 
    SELECT 
      MRN 
     , MIN(VisitDate) AS VisitDate 
     , MIN(NextDay) AS NextDay 
    FROM 
     a 
    GROUP BY 
     MRN 
), b AS (
    SELECT 
      VisitDate 
     , MRN 
     , NextDay 
     , 1 AS OrderRow 
    FROM 
     a1 

    UNION ALL 

    SELECT 
      a.VisitDate 
     , a.MRN 
     , a.NextDay 
     , b.OrderRow +1 AS OrderRow 
    FROM 
     a 
     JOIN b 
     ON a.VisitDate = b.NextDay 
), c AS (
SELECT 
    MRN, 
    VisitDate 
    , (SELECT MAX(VisitDate) FROM b WHERE b1.VisitDate > VisitDate AND b.MRN = b1.MRN) AS PreviousVisitDate 
FROM 
    b b1 
) 
SELECT distinct 
    c1.MRN, 
    c1.VisitDate 
    , CASE 
     WHEN DATEDIFF(day,c1.PreviousVisitDate,c1.VisitDate) < 30 THEN PreviousVisitDate 
     ELSE NULL 
    END AS ReAdmissionFrom 
    , CASE 
     WHEN DATEDIFF(day,c1.PreviousVisitDate,c1.VisitDate) < 30 THEN 3 
     ELSE 0 
    END AS Points 
FROM 
    c c1 
ORDER BY c1.MRN 

Erwartete Ergebnisse:

MRN VisitDate ReAdmissionFrom Points 
1 2016-01-02 NULL   0 
1 2016-01-07 2016-01-02  3 
1 2016-02-04 2016-01-07  3 
1 2016-06-02 NULL   0 
1 2016-06-06 2016-06-02  3 
1 2016-07-01 2016-06-06  3 
1 2016-08-01 NULL   0 
1 2016-08-15 2016-08-01  3 
1 2016-08-28 2016-08-15  3 
1 2016-10-12 NULL   0 
1 2016-11-17 NULL   0 
1 2016-12-20 NULL   0 
+0

Sie, was Sie beschreiben sollten versuchen zu tun, einschließlich Beispieldaten und gewünschten Ergebnissen. –

+1

Ich schlage auch vor, dass Sie dies auf der codereview.stackexchange.com Website – scsimon

+0

veröffentlichen Ich ging voran und veröffentlichte meine erwarteten Ergebnisse. – JBritton

Antwort

1

oops änderte ich die Namen von einigen CTE (und die Post vermasselt, was Code war)

Es sollte so aussehen:

b AS ( SELECT VisitDate , MRN , NextDay , 1 AS OrderRow VON a1

UNION ALL 

SELECT 
     a.VisitDate 
    , a.MRN 
    , a.NextDay 
    , b.OrderRow +1 AS OrderRow 
FROM 
    a AS a 
    JOIN b 
    ON a.VisitDate = b.NextDay AND a.MRN = b.MRN 

)

+3

Bitte bearbeiten Sie einfach Ihre ursprüngliche Antwort, anstatt eine neue zur Korrektur hinzuzufügen. –

+0

Danke Ivan. Es läuft jetzt in <10 Sekunden! Nach dem Testen musste ich auch RiskReadmits.MRN = Z1.MRN in der Unterabfrage in a festlegen. – JBritton

0

ich hier eine wilde Vermutung nehmen werde und sagen Sie die b CTE haben UND a.MRN = b.MRN als zweites ändern möchten Zustand in der zweiten SELECT-Abfrage wie folgt aus:

, b AS (
    SELECT 
      VisitDate 
     , MRN 
     , NextDay 
     , 1 AS OrderRow 
    FROM 
     firstVisitAndFollowUp 

    UNION ALL 

    SELECT 
      a.VisitDate 
     , a.MRN 
     , a.NextDay 
     , b.OrderRow +1 AS OrderRow 
    FROM 
     visitsDistance3daysOrMore AS a 
     JOIN b 
     ON a.VisitDate = b.NextDay AND a.MRN = b.MRN 
) 
Verwandte Themen