views:

264

answers:

3

I have a single table that houses student scores by their classes. For example, each class has 30 students, so there are 30 scores for each class. I'd like to do a simple report that averages, does a median, and a mode, for each data set per class. So, each class will have an average, a median, and a mode. I know that SQL Server does not have a built in function for median and mode, and I found sample SQLs for the median. However, the samples I found do not do any grouping, I found:

SELECT
(
 (SELECT MAX(Value) FROM
   (SELECT TOP 50 PERCENT Value FROM dbo.VOrders ORDER BY Value) AS H1)
 +
 (SELECT MIN(Value) FROM
   (SELECT TOP 50 PERCENT Value FROM dbo.VOrders ORDER BY Value DESC) AS H2)
) / 2 AS Median

Is it possible to modify to add a group by so I get a median value per class?

A: 
example data:
1, homer, 100, BIO 
2, marge, 90, BIO 
3, bart, 85, BIO 
4, lisa, 100, CHEM 
5, henry, 55, CHEM 
6, jed, 77, CHEM
bmw0128
don't know how to format comments so i put the data set here
bmw0128
would like the stats per class
bmw0128
i don;t think i was clear enough, i'd like the SQL to return one data set, looking something like this: MEDIAN CLASS ====== ===== 90 BIO 77 CHEM
bmw0128
A: 

i don;t think i was clear enough, i'd like the SQL to return one data set, looking something like this:

MEDIAN CLASS 
====== ===== 
 90     BIO 
 77     CHEM
bmw0128
A: 

this is the answer:

WITH CTE AS (
SELECT e_id, 
   scale, 
   ROW_NUMBER() OVER(PARTITION BY e_id ORDER BY scale ASC) AS rn,   
   COUNT(scale) OVER(PARTITION BY e_id) AS cn
FROM waypoint.dbo.ScoreMaster
WHERE scale IS NOT NULL
)
SELECT e_id,

cast(AVG (cast(scale as decimal(5,2))) as decimal(5,3)) as [AVG],
cast (STDEV(cast(scale as decimal(5,1))) as decimal(5,3)) as [STDDEV],   
AVG(CASE WHEN 2 * rn - cn BETWEEN 0 AND 2 THEN scale END) AS FinancialMedian,
MAX(CASE WHEN 2 * rn - cn BETWEEN 0 AND 2 THEN scale END) AS StatisticalMedian

from CTE
GROUP BY e_id
bmw0128