我有一个看起来像这样的表:
+----+-----------+-------+
| id | subject | grade |
+----+-----------+-------+
| 1 | english | 2 |
| 1 | math | 3 |
| 1 | physics | 1 |
| 1 | chemistry | 1 |
| 1 | biology | * |
| 2 | english | 1 |
+----+-----------+-------+
我想运行
AVG(grade) OVER (PARTITION BY id ORDER BY id DESC) AS 'Average Grade'
但是,当然,因为*,A,B等等级,所以不起作用。
有没有一种方法可以告诉AVG在其计算中将字母替换为任意值,例如
*。 *
= 0
*。 A = 1
*。 B = 2
并忽略N / A或X等字段。
预先感谢
编辑:
我的DBMS是Sql Server
答案 0 :(得分:3)
您可以尝试在CASE WHEN
函数中使用AVG
。
AVG(CASE WHEN grade = '*' THEN 0
WHEN grade = 'A' THEN 1
WHEN grade = 'B' THEN 2
....
ELSE grade END) OVER (PARTITION BY id ORDER BY id DESC) AS 'Average Grade'
注意
我建议您将grade
设置为int dataType而不是字符串,因为这样可以更容易计算。
答案 1 :(得分:1)
您可以在case
中使用巨型avg()
表达式。但是,我建议您有一个引用表或至少一个派生表来处理映射:
第二(partition by id order by id)
没有道理。您想要id
的完整平均值(我的猜测),还是想要一个连续平均值。所以,
select avg(v.grade_val) over (partition by t.id) as id_average_grade
from t outer apply
(select
from (values ('A', 1), ('B', 2), ('*', 0), ('1', 1), ('2', 2), . . .
) v(grade, grade_val)
where v.grade = t.grade
) v(grade_val)
请注意,内部values()
可能是善意参考表。