2017-03-07 37 views
1

SQL Server 2008を使用していて、日付範囲の中央値を計算しようとしています。SQL:各日付範囲の中央値を計算します。

例:日付ごとに複数の値(1/1/16、3/1/16,7/1/16,10/1/16)、日付10の中央値/ 1/16は、日付範囲1/1/16 - 7/1/16の値から計算されます。日付7/1/16の中央値は、日付範囲1/1/16〜3/1/16の値から計算されます。

日付が10/1/16の場合、10/1/16の値は中央値に含めてはいけません(これはすべての日付で当てはまります。また、将来の日付は計算に含めないでください)。

以下のクエリは、MAX訪問日の中央値を計算します。しかし、他の3訪問日の中央値も計算する必要があります。 MAX CTEを削除し、すべての訪問日に参加を追加しようとしました<訪問日よりも、私はそれを動作させることができませんでした。私は今までこれを書いて失敗しているので、どんな助けも素晴らしいだろう。サンプルデータと期待される結果を以下に掲載しました。

EDIT:再帰のいくつかの種類が動作する可能性がありますか?

;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

2008年にPERCENTILE_DISCは認識されません。 – JBritton

答えて

1

これをテストするSQL Server 2008のボックスはありません。そこで、以下のすべての関数をクロスチェックするために最善を尽くしました。

;WITH 
    tmp AS 
    (
     SELECT   a.QUESTION 
        , a.VISIT_DATE 
        , b.VALUE 
        , ROW_NUMBER() OVER (PARTITION BY a.QUESTION, a.VISIT_DATE ORDER BY b.VALUE) 
                   AS RowNumber 
        , FLOOR(CONVERT(float, COUNT(b.Value) OVER (PARTITION BY a.QUESTION, a.VISIT_DATE) + 1)/2) 
                   AS LowerMedianRowNumber 
        , CEILING(CONVERT(float, COUNT(b.Value) OVER (PARTITION BY a.QUESTION, a.VISIT_DATE) + 1)/2) 
                   AS UpperMedianRowNumber 
     FROM   (
          SELECT DISTINCT 
             QUESTION 
            , VISIT_DATE 
          FROM  #TEST 
         )  a 
     INNER JOIN  #TEST b ON a.QUESTION = b.QUESTION 
            AND a.VISIT_DATE > b.VISIT_DATE 

    ), 
    GroupMedian AS 
    (
     SELECT   QUESTION 
        , VISIT_DATE 
        , AVG(Value)  AS MedianValue 
     FROM   tmp 
     WHERE   RowNumber IN (LowerMedianRowNumber, UpperMedianRowNumber) 
     GROUP BY  QUESTION 
        , VISIT_DATE 
    ) 

SELECT   a.* 
     ,  b.MedianValue 
FROM   #TEST   a 
LEFT JOIN  GroupMedian  b ON a.QUESTION = b.QUESTION 
            AND a.VISIT_DATE = b.VISIT_DATE 
ORDER BY  QUESTION 
     ,  VISIT_DATE 
関連する問題