• Based on the stated requirements... I think this is what you're looking for...

    IF OBJECT_ID('tempdb..#temp') IS NOT NULL

    DROP TABLE #temp;

    CREATE TABLE #temp([term] int,

    [course] varchar(10),

    [mark] float);

    INSERT INTO #temp (term,course,mark) VALUES

    (1,'math',3),

    (1,'eng',4),

    (1,'hist',4.5),

    (1,'anth',4.5),

    (2,'comp',3),

    (2,'math',4),

    (2,'bio',4.5),

    (2,'chem',4.5),

    (3,'soc',4.5),

    (3,'math',4.5),

    (3,'bio',4),

    (3,'chem',4);

    WITH NewMark AS (

    SELECT

    t.term,

    CASE WHEN t.mark = MAX(t.mark) OVER (PARTITION BY t.course ORDER BY t.course, t.term) THEN t.mark END AS NewMark

    FROM

    #temp t

    ), AvgPrep AS (

    SELECT

    nm.term,

    COUNT(nm.NewMark) * 1.0 AS CourseCount,

    SUM(nm.NewMark) * 1.0 MarkSum

    FROM

    NewMark nm

    GROUP BY

    nm.term

    )

    SELECT

    ap.term,

    SUM(ap.MarkSum) OVER (ORDER BY ap.term) / SUM(ap.CourseCount) OVER (ORDER BY ap.term) AS RunningAvg

    FROM

    AvgPrep ap

    Here are the results...

    term RunningAvg

    ----------- ----------------------

    1 4

    2 4

    3 4.1