SQL中的AVG或SUM,其中的值是即时计算的

时间:2015-01-22 15:35:27

标签: mysql sql

我有一个现有的SQL查询,可以从Zultys MX250电话系统获取呼叫统计数据: -

SELECT
    CONCAT(LEFT(u.firstname,1),LEFT(u.lastname,1)) AS Name,
    sec_to_time(SUM(
        time_to_sec(s.disconnecttimestamp) - time_to_sec(s.connecttimestamp)
    )) AS Duration,
    COUNT(*) AS '#Calls'
FROM
    session s
    JOIN mxuser u ON
        s.ExtensionID1 = u.ExtensionId
        OR s.ExtensionID2 = u.ExtensionId
WHERE
    s.ServiceExtension1 IS NULL
    AND s.connecttimestamp >= CURRENT_DATE
    AND BINARY u.userprofilename = BINARY 'DBAM'
GROUP BY
    u.firstname,
    u.lastname
ORDER BY
    '#Calls' DESC,
    Duration DESC;

输出如下: -

Name    Duration        #Calls
TH      01:19:10        30
AS      00:44:59        28
EW      00:51:13        22
SH      00:21:20        13
MG      00:12:04        8
TS      00:42:02        5
DS      00:00:12        1

我正在尝试生成第4列,显示每个用户的平均通话时间,但我正在努力弄清楚如何。

数学上它只是“'持续时间'/'#Calls'”但在查看StackOverflow上的一些类似问题之后,示例查询太简单了,无法帮助我与上面的相关。

现在,我甚至不确定是否可以将时间列除以通话次数。

更新:我在我的测试中非常接近但是让所有人感到困惑和放松过于复杂的事情。这是最新的SQL(感谢@ McAdam331和我的好友Jim来自工作): -

SELECT
    CONCAT(LEFT(u.firstname,1),LEFT(u.lastname,1)) AS Name,
    sec_to_time(SUM(
        time_to_sec(s.disconnecttimestamp) - time_to_sec(s.connecttimestamp)
    )) AS Duration,
    COUNT(*) AS '#Calls',
    sec_to_time(SUM(time_to_sec(s.disconnecttimestamp) - time_to_sec(s.connecttimestamp)) / COUNT(*)) AS Average
FROM
    session s
    JOIN mxuser u ON
        s.ExtensionID1 = u.ExtensionId
        OR s.ExtensionID2 = u.ExtensionId
WHERE
    s.ServiceExtension1 IS NULL
    AND s.connecttimestamp >= CURRENT_DATE
    AND BINARY u.userprofilename = BINARY 'DBAM'
GROUP BY
    u.firstname,
    u.lastname
ORDER BY
    Average DESC;

输出如下: -

Name    Duration        #Calls  Average
DS      00:14:25        4       00:03:36
MG      00:17:23        11      00:01:34
TS      00:33:38        22      00:01:31
EW      01:04:31        43      00:01:30
AS      00:49:23        33      00:01:29
TH      00:43:57        35      00:01:15
SH      00:13:51        12      00:01:09

3 个答案:

答案 0 :(得分:1)

嗯,你可以获得总秒数,就像你把它转换成时间一样。为什么不采用总秒数,除以调用次数,然后将其转换回时间?

SELECT sec_to_time(
   SUM(time_to_sec(s.disconnecttimestamp) - time_to_sec(s.connecttimestamp)) / COUNT(*)) 
   AS averageDuration

答案 1 :(得分:0)

如果我理解正确,您只需将sum()替换为avg()

即可
SELECT
    CONCAT(LEFT(u.firstname,1),LEFT(u.lastname,1)) AS Name,
    sec_to_time(SUM(
        time_to_sec(s.disconnecttimestamp) - time_to_sec(s.connecttimestamp)
    )) AS Duration,
    COUNT(*) AS `#Calls`,
    sec_to_time(AVG(
        time_to_sec(s.disconnecttimestamp) - time_to_sec(s.connecttimestamp)
    )) AS AvgDuration

答案 2 :(得分:0)

似乎所有你需要的是SELECT列表中的另一个表达式。 SUM()聚合(来自第二个表达式)除以COUNT聚合(第三个expr)。然后将其包装在sec_to_time函数中。 (除非我完全错过了这个问题。)

就个人而言,我使用TIMESTAMPDIFF函数来获得时间差异。

SEC_TO_TIME(
  SUM(TIMESTAMPDIFF(SECOND,s.connecttimestamp,s.disconnecttimestamp))
  / COUNT(*)
) AS avg_duration

如果您要问的是,有一种方法可以通过别名引用SELECT列表中的其他表达式......不幸的是,答案是不存在的。

由于性能下降,您可以将现有查询用作内联视图,然后在外部查询中,分配给表达式的别名可用...

SELECT t.Name
     , SEC_TO_TIME(s.TotalDur) AS Duration
     , s.`#Calls`
     , SEC_TO_TIME(s.TotalDur/s.`#Calls`) AS avgDuration
  FROM (
         SELECT CONCAT(LEFT(u.firstname,1),LEFT(u.lastname,1)) AS Name
              , SUM(TIMESTAMPDIFF(SECOND,s.connecttimestamp,s.disconnecttimestamp)) AS TotalDur
              , COUNT(1) AS `#Calls`
           FROM session s 
               -- the rest of your query
       ) t