想知道是否有办法在一个MySQL查询中编写以下内容。
我有一张桌子: cust_ID | rpt_name | req_secs
在我想要的查询中:
按cust_ID分组的AVG req_secs
按rpt_name
分组时的AVG req_secs总req_secs AVG
我知道我可以在同一个表上执行单独的分组查询,然后将结果UNION为一个。但是我希望在一个查询中有一些方法可以做到这一点。
感谢。
答案 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_id
和rpt_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作为一种方便的方法将三个文字值作为行集返回,所以我可以将它连接到原始表。