SQL Query ... небольшая помощь с AVG и MEDIAN с использованием DISTINCT и SUM - PullRequest
2 голосов
/ 07 августа 2011

У меня есть запрос, чтобы узнать общую продолжительность использования телефона различными пользователями ...

Но мне нужно иметь возможность определять различные средние значения для их использования ... проблема в том, что некоторые пользователи используют телефоны совместно, и я могу только получать информацию о телефоне, поэтому длительность звонка повторяется, и это искажает данные ..

Так что мне нужно среднее и отличное (в поле pin.Number) ... было бы также полезно сделать медиану, если это возможно .. ??

Это текущий запрос ...

SELECT TOP 40 SUM(Duration) AS TotalDuration, c.Caller, oin.Name, oin.Email, pin.Number, oin.PRN 
FROM Calls as c 
INNER JOIN Phones as pin On c.caller = pin.id 
INNER JOIN officers as oin On pin.id = oin.fk_phones 
WHERE Duration <> 0 AND Placed BETWEEN '01/07/2011 00:00:00' AND '20/08/2011 23:59:59' 
GROUP BY c.Caller, oin.Name, pin.Number, oin.Email, oin.PRN 
ORDER BY TotalDuration DESC  

Большое спасибо за любые указатели

Вот пример текущих данных, которые я получаю (но я добавил средние значения, которые ниже, чем я), поскольку вы можете видеть, что некоторые пользователи используют один и тот же телефон, но количество секунд разделяется между ними, так что не хочу, чтобы это влияло на среднее значение (я не хочу, чтобы 11113 секунды повторялись), поэтому на каждом номере должен быть отдельный номер.

enter image description here

Ответы [ 2 ]

2 голосов
/ 07 августа 2011

Вот решение, которое реализует следующую идею:

  1. Получить итогов за телефон (SUM(Duration)).

  2. Ранг результирующий набор по значениям общей длительности (ROW_NUMBEROVER (ORDER BY SUM(Duration))).

  3. Включите еще один столбец для общего количества строк (COUNT(*)OVER ()).

  4. Из полученного набора получаем среднее (AVG(TotalDuration)).

  5. Получите медиану как среднее между двумя значениями, рейтинг которых равен

    1) N div 2 + 1,

    2) N div 2 + N mod 2,

    , где N - количество элементов, div - оператор целочисленного деления и mod - оператор по модулю.

Мой тестовый стол:

DECLARE @Calls TABLE (Caller int, Duration int);
INSERT INTO @Calls (Caller, Duration)
SELECT 3, 123 UNION ALL
SELECT 1,  23 UNION ALL
SELECT 2,  15 UNION ALL
SELECT 1, 943 UNION ALL
SELECT 3, 326 UNION ALL
SELECT 3,  74 UNION ALL
SELECT 9,  49 UNION ALL
SELECT 5,  66 UNION ALL
SELECT 4,  56 UNION ALL
SELECT 4, 208 UNION ALL
SELECT 4, 112 UNION ALL
SELECT 5, 521 UNION ALL
SELECT 6, 197 UNION ALL
SELECT 8,  23 UNION ALL
SELECT 7,  22 UNION ALL
SELECT 1,  24 UNION ALL
SELECT 0,  45;

Запрос:

WITH totals AS (
  SELECT
    Caller,
    TotalDuration = SUM(Duration),
    rn = ROW_NUMBER() OVER (ORDER BY SUM(Duration)),
    N = COUNT(*) OVER ()
  FROM @Calls
  GROUP BY Caller
)
SELECT
  Average = AVG(TotalDuration),
  Median = AVG(CASE WHEN rn IN (N / 2 + 1, N / 2 + N % 2) THEN TotalDuration END)
FROM totals

Выход:

Average     Median
----------- -----------
282         123

Примечание. В Transact-SQL / обозначает целочисленное деление, если оба операнда целочисленные. Оператор по модулю в T-SQL: %.

1 голос
/ 07 августа 2011

Я надеюсь, что вы можете использовать это, я сделал это с временными таблицами

declare @calls table (number char(4), duration int)
declare @officers table(number char(4), name varchar(10))

insert @calls values (3321,1)
insert @calls values (3321,1)
insert @calls values (3321,1)
insert @calls values (3321,42309)

insert @calls values (1235,34555)
insert @calls values (2979,31133)
insert @calls values (2324,24442)
insert @calls values (2345,11113)
insert @calls values (3422,9922)
insert @calls values (3214,8333)


insert @officers values(3321, 'Peter')
insert @officers values(1235, 'Stewie')
insert @officers values(2979, 'Lois')
insert @officers values(2324, 'Brian')
insert @officers values(2345, 'Chris')
insert @officers values(2345, 'Peter')
insert @officers values(3422, 'Frank')
insert @officers values(3214, 'John')
insert @officers values(3214, 'Mark')

Sql для получения среднего и среднего

;with a as 
(
select sum(duration) total_duration, number from @calls group by number
)
select avg(a.total_duration) avg_duration, c.total_duration median_duration from a
cross join (
select top 1 total_duration from (
select top 50 percent total_duration from a order by total_duration desc) b order by
total_duration) c
group by c.total_duration

Попробуйте здесь: http://data.stackexchange.com/stackoverflow/q/108612/

Sql Для получения общей продолжительности

select o.name, c.total_duration, c.number from @officers o join
(select sum(duration) total_duration, number from @calls group by number) c
on o.number = c.number
order by total_duration desc

Попробуйте здесь: http://data.stackexchange.com/stackoverflow/q/108611/

...