首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL优化avg、sum查询具有left join嵌套select

问MySQL优化avg、sum查询具有left join嵌套select
EN

Stack Overflow用户
提问于 2015-09-22 05:01:38
回答 2查看 146关注 0票数 0

是不是要为MySQL 5.1优化这个查询?

我有“呼叫”表,有字段“呼叫者”(从号码),“被呼叫者”(到号码)和“持续时间”,这个查询在SQLite中工作得很好,但它在MySQL中非常慢,有140亿条巨大的数据记录。

我有Caller字段的索引。

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2015-09-22 05:06:18

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

代码语言:javascript
复制
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,那么aCallOut可能会减少1。

票数 1
EN

Stack Overflow用户

发布于 2015-09-22 05:10:23

要合并前两个...

代码语言:javascript
复制
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行,则可能会出现除以零错误。

Edit#2:在NULLIF(,0)中包装分母可以避免这种错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32704502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档