一个MySQL查询通过不同的分组获得AVERAGE?

时间:2013-07-16 17:57:32

标签: mysql group-by average

想知道是否有办法在一个MySQL查询中编写以下内容。

我有一张桌子: cust_ID | rpt_name | req_secs

在我想要的查询中:

按cust_ID分组的AVG req_secs

按rpt_name

分组时的AVG req_secs

总req_secs AVG

我知道我可以在同一个表上执行单独的分组查询,然后将结果UNION为一个。但是我希望在一个查询中有一些方法可以做到这一点。

感谢。

3 个答案:

答案 0 :(得分:1)

嗯,以下是三分之二:

select n,
       (case when n = 1 then cast(cust_id as varchar(255)) else rpt_name end) as grouping,
       avg(req_secs)
from t cross join
     (select 1 as n union all select 2
     ) n
group by n, (case when n = 1 then cust_id else rpt_name end);

这实质上是“加倍”数据,然后为每个组进行聚合。这假定cust_idrpt_name是兼容类型。 (如果不是这种情况,可以调整查询。)

实际上,您可以使用rollup

来获得整体平均值
select n,
       (case when n = 1 then cust_id else rpt_name end) as grouping,
       avg(req_secs)
from t cross join
     (select 1 as n union all select 2
     ) n
group by n, (case when n = 1 then cast(cust_id as varchar(255)) else rpt_name end) with rollup

这适用于平均值,因为“加倍”数据的平均值与原始数据相同。它不适用于sum()count()

答案 1 :(得分:0)

不,没有。您可以同时按cust_ID和rpt_name的组合进行分组(即两个分组级别),但您不能同时执行单独的顶级分组,然后执行非分组聚合。

答案 2 :(得分:0)

由于GROUP BY的工作方式,执行此操作的SQL有点棘手。获得结果的一种方法是获取行的三个副本,并分别对每组行进行分组。

SELECT g.gkey
     , IF(g.grp='cust_id',t.cust_ID,IF(g.grp='rpt_name',t.rpt_name,'')) AS gval
     , AVG(t.req_secs) AS avg_req_secs
  FROM (SELECT 'cust_id' AS gkey UNION ALL SELECT 'rpt_name' UNION ALL SELECT 'total') g
 CROSS
  JOIN mytable t
 GROUP 
    BY g.gkey
     , IF(g.grp='cust_id',t.cust_ID,IF(g.grp='rpt_name',t.rpt_name,''))

别名为“g”的内联视图不必使用UNION ALL运算符,只需要一个返回3行且具有不同值的行集。我只是使用UNION ALL作为一种方便的方法将三个文字值作为行集返回,所以我可以将它连接到原始表。