2010-02-07 2 views
0

Можно создать дубликат:
Function to Calculate Median in Sql ServerSQL функция для вычисления медианы

У меня есть таблица, содержащая два поля (более, но не имеет отношения). Поля - это цена и количество. Я хочу найти несколько статистических данных для этой таблицы, и среди них средняя цена при изменении количества.

Сегодня у меня есть базовая-медленно-не очень хорошая функция на месте, которая принимает общее количество и делится на 2. Затем я иду по записям, упорядоченным по цене, и вычитаю количество из общей суммы. Когда общее количество достигло 0, у меня есть медиана.

Как вы можете догадаться, это медленно ... очень медленно. Я ищу идеи о том, как сделать это лучше, быстрее и более супер-пупер.

Я использую MS SQL Express 2008 ...

+0

было предложено несколько раз, прежде чем HTTP: // stackoverflow.com/questions/1342898/function-to-calculate-median-in-sql-server – gbn

+0

Разве это не только один колум? Я не могу понять, как это относится к моей проблеме с двумя столбцами. – rozon

ответ

0

Это должно, по крайней мере сделать это только два запросов вместо цикла:

declare @total int 

select @total = sum(Quantity) from Products 

select top 1 p.Price 
from Products p 
order by abs((select sum(Quantity) from Products where Price < p.Price) - (@total/2)) 

Индекс по цене с Штук в области включены бы, вероятно, к чудесам для производительности ...

0

Я не рядом со своим ящиком SQL, чтобы прорыть материал OVER PARTITION, но, используя его, он должен делать то, что вы ищете. Проверьте раздел этой статьи SQL 2005 для примера: link text

0

Это, вероятно, самый лучший один я использовал в прошлом, не используя просмотров:

SELECT AVG(DISTINCT Quantity) 
    FROM (SELECT F1.ID, F1.Quantity, 
     SUM(CASE WHEN F2.Quantity < F1.Quantity THEN 1 ELSE 0 END), 
     SUM(CASE WHEN F2.Quantity = F1.Quantity THEN 1 ELSE 0 END), 
     SUM(CASE WHEN F2.Quantity > F1.Quantity THEN 1 ELSE 0 END) 
     FROM [Table] as F1, [Table] as F2 
     GROUP BY F1.ID, F1.Quantity) AS Partitions (ID, Quantity, Lesser, Equal, Greater) 
    WHERE Lesser = Greater 
    OR (Lesser <= (SELECT COUNT(*) FROM [Table])/2.0 AND Greater <= (SELECT COUNT(*) FROM [Table])/2.0);