我有以下表格数据:
value
1
5
10.5
12
36
我想将这些值映射到:
range avg
0-21 (1 + 5 + 10.5 + 12) / 4
21.001-34 0
34.001-64 36
64 + 0
基本上将每个值映射到范围,并计算每个范围内所有值的平均值。
我试图做:
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.将值映射到这些组中(0-21、21-34等。) 2.计算每组的AVG。
上面示例的期望输出是这样的:
range avg
0-21 7.125
21.001-34 0
34.001-64 36
64 + 0
range
列是静态的。始终带有5行。
avg
列是动态的。.值是value
列的实际AVG。
答案 0 :(得分:3)
您可以使用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)
范围内。
答案 1 :(得分:3)
您可以使用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
答案 2 :(得分:1)
您实际上不需要使用这些小数。
因为例如,如果“值”等于21,则CASE
在评估下一个WHEN
之前将已经返回0-21范围。
但是您仍然需要对范围进行分组。
要返回所有范围,无论它们是否缺失,您都可以连接到具有范围的子查询。
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 <>提琴here