Function to Calculate Median in SQL Server

前端 未结 30 2810
孤独总比滥情好
孤独总比滥情好 2020-11-22 04:03

According to MSDN, Median is not available as an aggregate function in Transact-SQL. However, I would like to find out whether it is possible to create this functionality (u

30条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-22 04:21

    I just came across this page while looking for a set based solution to median. After looking at some of the solutions here, I came up with the following. Hope is helps/works.

    DECLARE @test TABLE(
        i int identity(1,1),
        id int,
        score float
    )
    
    INSERT INTO @test (id,score) VALUES (1,10)
    INSERT INTO @test (id,score) VALUES (1,11)
    INSERT INTO @test (id,score) VALUES (1,15)
    INSERT INTO @test (id,score) VALUES (1,19)
    INSERT INTO @test (id,score) VALUES (1,20)
    
    INSERT INTO @test (id,score) VALUES (2,20)
    INSERT INTO @test (id,score) VALUES (2,21)
    INSERT INTO @test (id,score) VALUES (2,25)
    INSERT INTO @test (id,score) VALUES (2,29)
    INSERT INTO @test (id,score) VALUES (2,30)
    
    INSERT INTO @test (id,score) VALUES (3,20)
    INSERT INTO @test (id,score) VALUES (3,21)
    INSERT INTO @test (id,score) VALUES (3,25)
    INSERT INTO @test (id,score) VALUES (3,29)
    
    DECLARE @counts TABLE(
        id int,
        cnt int
    )
    
    INSERT INTO @counts (
        id,
        cnt
    )
    SELECT
        id,
        COUNT(*)
    FROM
        @test
    GROUP BY
        id
    
    SELECT
        drv.id,
        drv.start,
        AVG(t.score)
    FROM
        (
            SELECT
                MIN(t.i)-1 AS start,
                t.id
            FROM
                @test t
            GROUP BY
                t.id
        ) drv
        INNER JOIN @test t ON drv.id = t.id
        INNER JOIN @counts c ON t.id = c.id
    WHERE
        t.i = ((c.cnt+1)/2)+drv.start
        OR (
            t.i = (((c.cnt+1)%2) * ((c.cnt+2)/2))+drv.start
            AND ((c.cnt+1)%2) * ((c.cnt+2)/2) <> 0
        )
    GROUP BY
        drv.id,
        drv.start
    

提交回复
热议问题