2017-03-07 5 views
1

Ich verwende SQL Server 2008 und versuche, Medianwerte pro Datumsbereich zu berechnen.SQL: Berechne den Median für jeden Datumsbereich

Beispiel: Es gibt 4 Daten mit mehreren Werten an jedem Datum (1/1/16, 3/1/16, 7/1/16, 10/1/16), der Medianwert für Datum 10/1/16 würde aus den Werten im Datumsbereich 1/1/16 - 7/1/16 berechnet. Der Medianwert für Datum 01.07.16 würde aus den Werten im Datumsbereich 01.01.16 - 01.03.16 berechnet.

Wenn das Datum 01.10.16 ist, sollten die Werte vom 1.10.16 nicht im Median enthalten sein (Dies gilt für alle Daten. Auch zukünftige Daten sollten nicht in die Berechnung einbezogen werden).

Die folgende Abfrage berechnet den Medianwert für das MAX Visit Date. Aber ich brauche es, um den Median für die anderen 3 Besuchstermine zu berechnen. Ich habe versucht, das MAX CTE zu entfernen und eine Verbindung für alle Besuchsdaten < als Besuchsdatum hinzuzufügen, aber ich konnte es nicht zum Funktionieren bringen. Ich habe es bisher nicht geschafft, dies zu schreiben, daher wäre jede Hilfe großartig. Ich habe Beispieldaten und meine erwarteten Ergebnisse unten eingefügt.

EDIT: Würde eine Art von Rekursion möglicherweise funktionieren?

;CREATE TABLE #TEST(QUESTION VARCHAR(15), VISIT_DATE DATE, VALUE INT) 

;INSERT #TEST(QUESTION, VISIT_DATE, VALUE) 
VALUES 
('ABC', '1/1/2016', '80'), 
('ABC', '1/1/2016', '90'), 
('ABC', '1/1/2016', '100'), 
('ABC', '3/1/2016', '70'), 
('ABC', '3/1/2016', '80'), 
('ABC', '3/1/2016', '90'), 
('ABC', '3/1/2016', '100'), 
('ABC', '7/1/2016', '50'), 
('ABC', '7/1/2016', '60'), 
('ABC', '7/1/2016', '70'), 
('ABC', '10/1/2016', '10'), 
('ABC', '10/1/2016', '20'), 
('ABC', '10/1/2016', '30'), 
('ABC', '10/1/2016', '40') 


;WITH MAX_VISITDATE AS (
    SELECT MAX(VISIT_DATE) AS MAX_VISITDATE 
    FROM #TEST 
), MEDIAN AS (
    SELECT RN.Question, AVG(RN.VALUE) AS GroupMedianPastQtrs 
    FROM 
    ( SELECT QUESTION, VALUE, ROW_NUMBER() OVER (PARTITION BY QUESTION ORDER BY VALUE) AS ROWNUMBER, COUNT(*) OVER (PARTITION BY Question) AS QuestionCount 
     FROM #TEST T 
     WHERE VISIT_DATE NOT IN (SELECT MAX_VISITDATE FROM MAX_VISITDATE) 
    ) RN 
    WHERE RN.ROWNUMBER IN (RN.QuestionCount/2+1, (RN.QuestionCount+1)/2) 
    GROUP BY RN.Question 
) 
SELECT * 
FROM #TEST T 
INNER JOIN MEDIAN ON T.Question = MEDIAN.Question 

--Expected Results: 

Question|Visit_DAte |Value|GroupMedian | 
--------|-----------|-----|-------------| 
'ABC' |'1/1/2016' |'80' |''   |--No Median, no previous values 
'ABC' |'1/1/2016' |'90' |''   |--No Median, no previous values 
'ABC' |'1/1/2016' |'100'|''   |--No Median, no previous values 
'ABC' |'3/1/2016' |'70' |'90'   |--Median value from date 1/1/16 
'ABC' |'3/1/2016' |'80' |'90'   |--Median value from date 1/1/16 
'ABC' |'3/1/2016' |'90' |'90'   |--Median value from date 1/1/16 
'ABC' |'3/1/2016' |'100'|'90'   |--Median value from date 1/1/16 
'ABC' |'7/1/2016' |'50' |'90'   |--Median value from date range 1/1/16 to 3/1/16 
'ABC' |'7/1/2016' |'60' |'90'   |--Median value from date range 1/1/16 to 3/1/16 
'ABC' |'7/1/2016' |'70' |'90'   |--Median value from date range 1/1/16 to 3/1/16 
'ABC' |'10/1/2016'|'10' |'80'   |--Median value from date range 1/1/16 to 7/1/16 
'ABC' |'10/1/2016'|'20' |'80'   |--Median value from date range 1/1/16 to 7/1/16 
'ABC' |'10/1/2016'|'30' |'80'   |--Median value from date range 1/1/16 to 7/1/16 
'ABC' |'10/1/2016'|'40' |'80'   |--Median value from date range 1/1/16 to 7/1/16 
+0

Ich glaube nicht, dass PERCENTILE_DISC in 2008 anerkannt wird. – JBritton

Antwort

1

Ich habe keine SQL Server 2008-Box, um dies zu testen. So versuchte ich mein Bestes, um jede Funktion zu überprüfen unten ist in 2008 verfügbar:

Verwandte Themen