MySQL - 选择列表的平均值但忽略最大值和最小值
Posted
技术标签:
【中文标题】MySQL - 选择列表的平均值但忽略最大值和最小值【英文标题】:MySQL - select avg of list but ignore max and min value 【发布时间】:2019-08-07 12:43:49 【问题描述】:我的数据库中有一个值列表。
k v
1 5000
1 100
1 120
1 3
2 5000
2 100
2 120
2 4
3 10000
3 120
3 100
3 4
4 10
4 120
4 110
4 5000
我想计算每个 k 的平均值,但我需要忽略每个 k 的 v 的最高和最低值。 (去除尖刺)
select avg(v) from table where v > min(v) and v < max(v) group by k
导致:
“组函数的无效使用”
我认为这是一项非常常见的任务,但我无法从文档中找到任何想法。
感谢您的建议。
【问题讨论】:
你的主键是什么?期望的结果应该是什么样的? 这不是你应该避免尖峰的方式 避免尖峰的方法是? 对于每个k
,您的样本显示v
的两个值。如果你想忽略 v 的最小值和最大值,你将没有任何东西可以计算平均值。 (或者也许我不明白你在寻找什么,你可以展示一个预期的结果。)
当然我在数据库中有更多的值。我已经更改了示例以使其清楚
【参考方案1】:
一种无需担心v
是否存在重复的最小值和最大值(假设您只想忽略其中一个)的方法是将平均值作为SUM(v)/COUNT(v)
,但减去最小值和最大值计算值:
SELECT k, (SUM(v) - MAX(v) - MIN(v)) / (COUNT(v) - 2) AS average
FROM data
GROUP BY k
输出:
k average
1 110
2 110
3 110
4 115
Demo on dbfiddle
【讨论】:
每个k的平均值 @MikeNathas 抱歉 - 感谢您指出这一点,我在问题中错过了它。【参考方案2】:select avg(v) , k
from table
group by k
having k <> min (v) and k<> max (v)
【讨论】:
【参考方案3】:首先获取每个k
的最小值和最大值v
,然后将left join
表格获取到结果,以便获得不匹配行的平均值:
select
t.k, avg(t.v) average
from tablename t left join (
select k, min(v) minv, max(v) maxv
from tablename
group by k
) g on g.k = t.k and t.v in (g.minv, g.maxv)
where g.k is null
group by t.k
请参阅demo。 结果:
| k | average |
| --- | ------- |
| 1 | 110 |
| 2 | 110 |
| 3 | 110 |
| 4 | 115 |
【讨论】:
【参考方案4】:链接: Demo
select t1.k, avg(t1.v) average
from numbers t1 left join (
select k, min(v) minv, max(v) maxv
from numbers
group by k
) t2 on t2.k = t1.k and t1.v in (t2.minv, t2.maxv)
where t2.k is null
group by t1.k
【讨论】:
以上是关于MySQL - 选择列表的平均值但忽略最大值和最小值的主要内容,如果未能解决你的问题,请参考以下文章