2009-10-13 246 views
0

我需要计算一组数据的中位数,所以我创建了一个临时表,并试着在网上遵循一些文章与零次的成功,这里是我与合作:如何计算中位数?

CREATE TABLE #QuizTemp (QuizProfileID INT,Cnt INT,TotalScore INT) 

INSERT INTO #QuizTemp 
SELECT QuizAnswers.QuizProfileID, COUNT(QuizAnswers.QuizProfileID) AS Cnt, SUM(QuizAnswers.AnsweredYes) As TotalScore 
FROM   QuizAnswers INNER JOIN 
         Quizzes ON QuizAnswers.QuizID = Quizzes.QuizID 
WHERE  (Quizzes.PartnerID = 16) 
GROUP BY QuizAnswers.QuizProfileID 
HAVING COUNT(QuizAnswers.QuizProfileID)= 5 

SELECT COUNT(*) AS CNT, Avg(TotalScore) AS AvgTotalScore FROM #QuizTemp 

DROP TABLE #QuizTemp 

平均工作很好,现在我需要中位数。

回答

1

尝试捕获的行数上插入,然后选择使用ROW_NUMBER()是在中间行:

CREATE TABLE #QuizTemp (QuizProfileID INT,Cnt INT,TotalScore INT) 
DECLARE @Rows int 

INSERT INTO #QuizTemp 
SELECT QuizAnswers.QuizProfileID, COUNT(QuizAnswers.QuizProfileID) AS Cnt, SUM(QuizAnswers.AnsweredYes) As TotalScore 
FROM   QuizAnswers INNER JOIN 
         Quizzes ON QuizAnswers.QuizID = Quizzes.QuizID 
WHERE  (Quizzes.PartnerID = 16) 
GROUP BY QuizAnswers.QuizProfileID 
HAVING COUNT(QuizAnswers.QuizProfileID)= 5 


DECLARE @Rows int 
SELECT @[email protected]@Rowcount 

;with allrows as 
(
    SELECT TotalScore, ROW_NUMBER() (ORDER BY TotalScore) AS RowNumber 

) 
SELECT @Rows AS CNT, TotalScore AS MedianScore 
FROM allrows WHERE [email protected]/2 


DROP TABLE #QuizTemp 

编辑

这里是一个没有临时表的解决方案:

DECLARE @YourTable table (TotalScore int) 
INSERT INTO @YourTable Values (1) 
INSERT INTO @YourTable Values (2) 
INSERT INTO @YourTable Values (3) 
INSERT INTO @YourTable Values (40) 
INSERT INTO @YourTable Values (50) 
INSERT INTO @YourTable Values (60) 
INSERT INTO @YourTable Values (70) 

;with allrows as 
(
    SELECT 
     TotalScore, ROW_NUMBER() OVER (ORDER BY TotalScore) AS RowNumber 
     FROM @YourTable 
) 
,MaxRows AS 
(SELECT MAX(RowNumber) AS CNT,CONVERT(int,ROUND(MAX(RowNumber)/2.0,0)) AS Middle FROM allrows) 
SELECT 
    m.CNT 
    ,(SELECT AVG(TotalScore) FROM allrows) AS AvgTotalScore 
    ,a.TotalScore AS Median 
    ,m.Middle AS MedianRowNumber 
    FROM allrows    a 
     CROSS JOIN MaxRows m 
    WHERE a.RowNumber=m.Middle 

OUTPUT:

CNT     AvgTotalScore  Median  MedianRowNumber 
-------------------- -------------------- ----------- -------------------- 
7     32     40   4 

(1 row(s) affected) 
如果编辑第一CTE是

;with allrows as 
(
    SELECT QuizAnswers.QuizProfileID, COUNT(QuizAnswers.QuizProfileID) AS Cnt, SUM(QuizAnswers.AnsweredYes) As TotalScore 
    , ROW_NUMBER() OVER (ORDER BY TotalScore) AS RowNumber 
    FROM   QuizAnswers INNER JOIN 
          Quizzes ON QuizAnswers.QuizID = Quizzes.QuizID 
    WHERE  (Quizzes.PartnerID = 16) 
    GROUP BY QuizAnswers.QuizProfileID 
    HAVING COUNT(QuizAnswers.QuizProfileID)= 5 
) 

它应该工作您的查询

0

数值的中值往往超过虽然。请使用此示例:

DECLARE @testTable TABLE 
( 
    VALUE INT 
) 
--INSERT INTO @testTable -- Even Test 
--SELECT 3 UNION ALL 
--SELECT 5 UNION ALL 
--SELECT 7 UNION ALL 
--SELECT 12 UNION ALL 
--SELECT 13 UNION ALL 
--SELECT 14 UNION ALL 
--SELECT 21 UNION ALL 
--SELECT 23 UNION ALL 
--SELECT 23 UNION ALL 
--SELECT 23 UNION ALL 
--SELECT 23 UNION ALL 
--SELECT 29 UNION ALL 
--SELECT 40 UNION ALL 
--SELECT 56 

-- 
--INSERT INTO @testTable -- Odd Test 
--SELECT 3 UNION ALL 
--SELECT 5 UNION ALL 
--SELECT 7 UNION ALL 
--SELECT 12 UNION ALL 
--SELECT 13 UNION ALL 
--SELECT 14 UNION ALL 
--SELECT 21 UNION ALL 
--SELECT 23 UNION ALL 
--SELECT 23 UNION ALL 
--SELECT 23 UNION ALL 
--SELECT 23 UNION ALL 
--SELECT 29 UNION ALL 
--SELECT 39 UNION ALL 
--SELECT 40 UNION ALL 
--SELECT 56 


DECLARE @RowAsc TABLE 
(
    ID  INT IDENTITY, 
    Amount INT 
) 

INSERT INTO @RowAsc 
SELECT VALUE 
FROM @testTable 
ORDER BY VALUE ASC 

SELECT AVG(amount) 
FROM @RowAsc ra 
WHERE ra.id IN 
(
    SELECT ID 
    FROM @RowAsc 
    WHERE ra.id - 
    (
     SELECT MAX(id)/2.0 
     FROM @RowAsc 
    ) BETWEEN 0 AND 1 

)