Это не совсем новый ответ, поскольку он в основном расширяет ответ Марка Байера, но есть несколько вариантов для еще большего упрощения запроса.
Первое, что нужно сделать, это действительно использовать CTE.Вы можете не только иметь несколько CTE, но они могут ссылаться друг на друга.Имея это в виду, мы можем создать дополнительный CTE для вычисления медианы на основе результатов первого.Это инкапсулирует срединное вычисление и оставляет фактический SELECT делать только то, что ему нужно.Обратите внимание, что ROW_NUMBER () должен был быть перемещен в первый CTE.
;WITH cte AS
(
SELECT number, ROW_NUMBER() OVER(ORDER BY number) AS rn
FROM table1
),
med AS
(
SELECT AVG(number) AS median
FROM cte
WHERE cte.rn = ((SELECT COUNT(*) FROM cte) + 1) / 2
OR cte.rn = ((SELECT COUNT(*) FROM cte) + 2) / 2
)
SELECT cte.number, med.median
FROM cte
CROSS JOIN med
И чтобы еще больше снизить сложность, вы «могли» использовать настраиваемый агрегат CLR для обработки медианы (например, тот, который указанбесплатная библиотека SQL # на http://www.SQLsharp.com/ [автором которой я являюсь]).
;WITH cte AS
(
SELECT number
FROM table1
),
med AS
(
SELECT SQL#.Agg_Median(cte.number) AS median
FROM cte
)
SELECT cte.number, med.median
FROM cte
CROSS JOIN med