mysql如何获取特定范围内的平均值

yzxexxkh  于 2021-06-18  发布在  Mysql
关注(0)|答案(3)|浏览(375)

我有下表数据:

value
1
5
10.5
12
36

我想将这些值Map到:

range      avg
0-21       (1 + 5 + 10.5 + 12) / 4
21.001-34  0
34.001-64  36
64 +       0

基本上将每个值Map到各个范围,并计算每个范围内所有值的平均值。
我试着做:

select 
case
when avggeneral between 0 and 21 then ' 0-21'
when avggeneral between 21.00001 and 34 then ' 21-34'
when avggeneral between 34.00001 and 64 then ' 34-64'
else '64+'
end as 'range',
AVG(*) as 'avg'
from table

但这不管用。。。我不知道怎么做静态范围。。。
在mysql中如何做到这一点?
方法学应为:1。将值Map到这些组(0-21、21-34等)2。计算各组平均值。
上述示例的期望输出如下:

range      avg
0-21       7.125
21.001-34  0
34.001-64  36
64 +       0

这个 range 列是静态的。总是有5排。这个 avg 列是动态的。。这些值是实际的平均值 value 列。

hs1ihplo

hs1ihplo1#

您可以使用 UNION ALL 以及 LEFT JOIN 有了它:

SELECT CONCAT(IFNULL(ranges.min, '∞'), '-', IFNULL(ranges.max, '∞')) AS `range`, avg(value) AS avg
FROM (
    SELECT 0 AS min, 21 AS max UNION ALL
    SELECT 21, 34 UNION ALL
    SELECT 34, 64 UNION ALL
    SELECT 64, NULL
) AS ranges
LEFT JOIN t ON (ranges.min IS NULL OR value >= ranges.min) AND
               (ranges.max IS NULL OR value <  ranges.max)
GROUP BY ranges.min, ranges.max

注意,上面的查询将 20.9999 内部 [0-21) 以及 21.0000 内部 [21-34) 射程。

7kqas0il

7kqas0il2#

您可以使用union获得所需的结果,如下所示:

select '0-21' as Range1, coalesce(avg(avggeneral),0) as AVG from Table1
where avggeneral > 0 and avggeneral <= 21
union
select '21-34' as Range1, coalesce(avg(avggeneral),0) as AVG from Table1
where avggeneral > 21 and avggeneral <= 34
union
select '34-64' as Range1, coalesce(avg(avggeneral),0) as AVG from Table1
where avggeneral > 34 and avggeneral <= 64
union
select '64+' as Range1, coalesce(avg(avggeneral),0) as AVG from Table1
where avggeneral > 64

此处为sql

ve7v8dk2

ve7v8dk23#

你真的不需要用那些小数。
因为举例来说,如果“值”等于21,那么 CASE 在计算下一个之前已经返回0-21范围 WHEN .
但你还是需要在靶场上分组。
为了返回所有的范围,不管它们是否丢失,您可以将join留给一个包含这些范围的子查询。

SELECT Ranges.`range`, COALESCE(AVG(Q.`value`), 0) as `avg`
FROM
(
  SELECT 0 as `class`, ' 0-21' as `range`
  UNION ALL SELECT 21, '21-34'
  UNION ALL SELECT 34, '34-64'
  UNION ALL SELECT 64, '64+'
) Ranges
LEFT JOIN
(
  SELECT 
   `value`,
   case
   when `value` between  0 and 21 then 0
   when `value` between 21 and 34 then 21
   when `value` between 34 and 64 then 34
   when `value` > 64 then 64
   end as rangeclass
  FROM test
) Q ON Q.rangeclass = Ranges.`class`
GROUP BY Ranges.`class`, Ranges.`range`
ORDER BY Ranges.`class`

db<>在这里摆弄

相关问题