Skip to main content
Removed floating indentation on left
Source Link
forsvarir
  • 10.8k
  • 6
  • 47
  • 81
            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
            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
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
Source Link
brian
  • 31
  • 1

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