MySQL优化avg,sum查询已经离开了join嵌套选择

时间:2015-09-21 21:01:38

标签: mysql sql

无论如何要优化MySQL 5.1的查询?

我有“Calls”表,有“Caller”字段(来自数字),“Callee”(到数字)和“Duration”,这个查询在SQLite中工作得很好,但在MySQL中有很大的数据140亿记录。

我有来电者字段的索引。

select A.Caller, ifnull(aCallOut, 0) as CallOut, round((ifnull(aDuration, 0) / 60), 2) as Duration, round((ifnull(aAverage, 0) / 60), 2) as Average, Times, 0, 0, 0, 0
from
  (
    select Caller, sum(duration) as aDuration, count(*) Times -- sum of duration of each caller
    from Calls
    group by Caller
  ) As A

left join
  (
    select Caller, avg(duration) as aAverage -- i want avg duration of numbers that calling more than 0 seconds
    from Calls
    where Duration > 0
    group by Caller
  ) as C
  on A.Caller = C.Caller

left join
  (
    select Caller, count(*) as aCallOut -- i need to count how many numbers that caller called, ignoring the duplicating calls
    from
      (
        select Caller, count(*) aCount
        from Calls
        group by Caller, Callee
      ) as D
    group by Caller
  ) as B
  on A.Caller = B.Caller

2 个答案:

答案 0 :(得分:1)

您可以使用条件聚合完成所有这些:

.toolbar {
    position: absolute;
    right: 100px;
    bottom: 50px;
    left: 100px;
}

.toolbar::before {  
    position: absolute;
    right: -100px;
    bottom: -50px;
    left: -100px;
}

小记:如果select Caller, sum(duration) as aDuration, count(*) as Times, avg(case when duration > 0 then duration end) as aAverage, count(distinct Callee) as aCallOut from Calls group by Caller; 永远是Callee,那么NULL可能会被1关闭。

答案 1 :(得分:0)

合并前两个......

SELECT Caller
, sum(duration) as aDuration -- sum of duration of each caller
, count(*) Times
, SUM(IF(duration>0, duration, 0)) / NULLIF(SUM(IF(duration>0, 1, 0)),0)  -- avg(duration) as aAverage
FROM Calls
GROUP BY Caller

编辑:如果来电者没有duration > 0行,则可能会有零除错误。

编辑#2:在NULLIF(,0)中包装分母可以防止该错误。