今日我在刷题时遇到这样一个题,它提到了以下需求:
有一场节目表演,五名裁判会对节目提供1-10分的打分,节目最终得分为去掉一个最高分和一个最低分后的平均分。
存在以下一张表performence_detail,包含字段有performance_id,一号评委打分score_1,二号评委打分score_2,三号评委打分score_3,四号评委打分score_4,五号评委打分score_5,评分时间date。
我实现表如下
但是遇到一个问题,要想实现以上需求,就需要找到一行中的最大值和最小值,我们平时使用的聚合函数MAX()、MIN()只能针对分组后的列进行计算,也就是我们通常说的横表,而针对同一行的相同数据类型我们需要另寻出路。
我查找了网上相关资料找到了如下解决方案
SQL内置函数
GREATEST(value1,value2,...)
select performance_id,greatest(score_1,score_2,score_3,score_4,score_5) as great_score
from performance_detail
LEAST(value1,value2,...)
select performance_id,least(score_1,score_2,score_3,score_4,score_5) as least_score
from performance_detail
这两个函数满足以下规则
如果有任何参数
NULL
,则结果为NULL
。无需比较。如果所有参数都是整数值,则将它们作为整数进行比较。
如果至少一个参数为双精度,则将它们作为双精度值进行比较。否则,如果至少一个参数是一个 DECIMAL值,则将它们作为DECIMAL 值进行比较。
如果参数包含数字和字符串的混合,则将它们作为数字进行比较。
如果任何参数是非二进制(字符)字符串,则将参数作为非二进制字符串进行比较。
在所有其他情况下,将参数作为二进制字符串进行比较。
表行转换为列
除以以外我们还可以把横表转换为竖标,再使用聚合函数进行筛选最大值和最小值
由于MySQL不支持unpiovt转换函数,可以使用union 替代
select performance_id, 'score_1' scores, score_1 as score from performance_detail
union select performance_id, 'score_2' scores, score_2 as score from performance_detail
union select performance_id, 'score_3' scores, score_3 as score from performance_detail
union select performance_id, 'score_4' scores, score_4 as score from performance_detail
union select performance_id, 'score_5' scores, score_5 as score from performance_detail
order by performance_id
接下来就可以使用MAX()、MIN()函数分组找到最大值和最小值了。