2

我有一个查询来获取各种用户的电话使用总持续时间......

但我需要能够为他们的使用情况计算出不同的平均值。问题是某些用户共享电话,我只能获取电话信息,所以通话时间会重复,这会扭曲数据。

所以我需要一个平均值和一个不同的(在 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 秒),所以每个电话号码都需要有一个不同的..

在此处输入图像描述

4

2 回答 2

2

这是一个实现以下想法的解决方案:

  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 中的模运算符是%.

于 2011-08-07T13:49:49.480 回答
1

我希望你能用这个,我用临时表做的

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

在这里试试:https ://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

在这里试试:https ://data.stackexchange.com/stackoverflow/q/108611/

于 2011-08-07T13:45:33.590 回答