0

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

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

在查询中我想得到:

按 cust_ID 分组时的 AVG req_secs

按 rpt_name 分组时的 AVG req_secs

总 req_secs AVG

我知道我可以对同一张表进行单独的分组查询,然后将结果合并为一个。但我希望有某种方法可以在一个查询中做到这一点。

谢谢。

4

3 回答 3

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()or count()

于 2013-07-16T18:16:45.490 回答
0

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

于 2013-07-16T18:07:41.670 回答
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 作为将三个文字值作为行集返回的便捷方式,因此我可以将其加入到原始表中。

于 2013-07-16T18:21:13.327 回答