猜您喜欢::
查分表这事儿,实际上挺绕的 实际上写 SQL 查平均成绩,刚启动看的时候总认定是“调戏”数据库,结局一上手才发现全是坑。别急,咱们直接上锅。 假设你手里有个成绩表,名字叫 `sc`,表格子里装着学号、科目和分数。你直接想求“全班平均分”,那在 SQL 里就是两句:`SELECT AVG(sc.score) FROM sc GROUP BY sc.id`。这个命令读起来像天书,出于它把“分数”这一列叫成了 `sc.score`,这简直是程序员们的第一道拦路虎。 大量人一上来就写 `SELECT AVG(score) FROM sc;`,结局报错。
为啥?出于数据库有时候分不清数字和字符串。
要是 `score` 里混着“十分”、“两百分”这种带字眼的,要么某些表设计得比较旧,字段类型定义成 `varchar` 而不是 `decimal`,直接求平均就炸了。
这时候你得先查一下——`DESCRIBE table_name` 要么用 `SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='table_name'` 看看到底是数字还是文字。若是混着写,那就得改改,要么建个临时表存数值,要么用 `CAST` 函数把它硬是把文字给掰成数字。 那如何算平均呢?核心还是 `AVG()` 函数。但前提是,`AVG` 能干活。
要是表里有空值(NULL),要么某些字段是逻辑字段(比如“是否缺席”这种),随意一算,结局直接变成 0 要么报错。
这时候就得小心点,把空值过滤掉,要么确保你的数据库配置能填补缺漏。
还有那些自增 ID,别瞎搞,别随意用 `SELECT COUNT()` 去循环查,效率忒低还好办锁表,不如直接 `GROUP BY` 一下。 再说说具体如何算。你不想整一堆复杂的公式,就想直接拿总分除以人数。
那就有 `SELECT COUNT() / (SELECT COUNT() FROM sc WHERE id IN (SELECT id FROM sc WHERE score IS NOT NULL))`。
这个逻辑有点绕,出于分母得先求出来,故此得加个 `IN` 子句,还得把 `WHERE` 里的条件也复制进去。
不过这个写法在大数据量下性能会崩,出于条件里的列又加了又减,优化器得猜来猜去。
这时候就得有技巧了,利用覆盖索引。
要是你的表结构是 `id`, `name`, `score`,且 `(id, score)` 上有了联合索引,那 `WHERE score IS NOT NULL` 就能直接扫出结局,不用全表扫一遍。 自然,求平均值也不是一锤子买卖。
有时候你想算的“加权平均分”,要么“不同科目标平均分”,要么“及格率”,那就要 `GROUP BY` 了。`GROUP BY id` 别看好办,但要是有空值,得用 `WHERE score IS NOT NULL` 把脏数据捞出来,不然聚合结局会偏了。
比如你查各科平均,那得把 `id` 和 `score` 都放一起,`GROUP BY sc.id, sc.score`,但这会让索引失效,出于目前它是双列索引了。
这时候要是数据量不大,那就挺费事的;若数据量大,就得寻思用啥函数把分数归一化一下,要么把表结构改得再好好一点。 还有啊,大量人一上来就想用 `HOUR()` 要么 `DAY()` 这种函数,那是大错特错。SQL 的聚合函数里,`AVG`、`MAX`、`MIN`、`COUNT` 这些只能处理数值,不能处理日期、工夫要么字符串。你要是想把某个学生的成绩按小时算平均,那是做不了聚合的。
要不就你要把日期转化为数值,要么用窗口函数(不过那是更高级的玩法,一般/平平用户先别碰)。 再说说数据处理。
本来表里可能有一堆脏数据,比如有个学号写成了字符串 "2023001",而正常是数字 "0023001"。
要是你直接查平均分,可能出于字符串比较,害得结局全乱。
这时候最好的做法是,在写查询前,先跑个 `SELECT DISTINCT ID FROM sc` 看看 ID 长啥样,再用 `REPLACE(ID, '2023', '2023')` 这种替换函数去清洗掉格式难题。清洗完再算平均分,结局才稳当。 最终,千万别忘了权限难题。有些表是只读视图,要么成了共享表(Shared Table),直接查询会报错。
这时候要么建个视图 `CREATE VIEW avg_graph AS SELECT`,要么改表结构,要么申请权限。再想想,要是表里数据量忒大,直接 `UPDATE` 要么 `DELETE` 整表也不划算,得分批处理,不然数据库会崩。 总的来说,SQL 查平均分数,别总想着“直接查”,得先查结构、先查空值、再寻思索引、最终再寻思清洗。别看间或会写错,但只要把那些坑填好,查成绩这事儿也就没那么可怕了。毕竟代码嘛,写出来能跑通、能出数,就算完美了。
好文推荐::