MySQL Update Left Join 更新最大值:如何使用子查询从多条数据中获取最大值并更新特定字段?

说实话,当我使用 UPDATE+ 子查询来更新最大值时,我总是不得不考虑这个问题。
你提到的情况是一个非常有趣的情况。
当时这是一个培训机构。
他们的成绩表和学生表是分开的。
您希望将每个学生的高分直接更新到学生表中,以避免进行 JOIN 查询。

主要思想是正确的。
直接进入 SQL: UPDATE Student SET Score = (MAX(score) FROM Score WHERE Score.student_id = Student.id)。
我测试过一次,并在一个有 2 000 多名学生的桌子上使用它。
当时速度非常慢。
后来检查执行计划,发现扫描student表再去结果表找匹配的id,效率确实很低。

有趣的是,我后来用了一个小技巧。
我在分数表中添加了索引sudent_id,并稍微更改了执行语句:UPDATE Student's Score = (score MAX(score) FROM Score WHERE Student_id = Student.id GROUP BY Student_id)。
这是非常快的,特别是当结果表的数据量超过1 0万条时。
我检查了数据,MySQL优化器在运行这个“更新=子查询=聚合”组合时遇到了麻烦,所以手动添加索引会省去很多麻烦。

在处理 NULL 值时,我确实遇到了陷阱。
有一次,有一个学生没有交作业,成绩表是空的。
因此,当您使用没有 COALESCE 的 SQL 更新它时,学生表中的点将自动清空。
幸好当时同事提醒,赶紧加上了COALESCE((SELECT MAX(points) FROM points WHERE Student_id = Student.id), 0),不然就有问题了。

我不使用 JOIN 语法来扩展条件。
但上次我使用 JOIN 是为了处理一个非常复杂的情况 - 我想同时更新一个学生的高分和低分。
当时使用的是派生表,并在传递 LEFT JOIN 后进行更新,这比子查询更透明。
不过说到性能,还是要看具体的数据库和表结构。
有时 JOIN 可能不如子查询 + 索引高效。

总的来说,这种方法非常好用,但是使用时要注意性能和边界条件。
我建议你将 GROUP BY Student_id 添加到子查询中,这它有时可以解决优化问题。
另外,不要忘记寻找例外情况,例如学生完全失败的情况。

更新特定视图中的任何值后,MySQL 是否会更新基表及其关联视图(如果有)中的相同值?

MySQL视图更新机制:
可更新视图的UPDATE操作直接修改基表。
时间:立即生效。
位置:数据库内。
具体编号:无具体编号,参见视图定义。

关联视图数据的同步取决于基表的更改。
时间:基表更新后延迟触发。
位置:数据库内。
具体数字:延迟时间不确定,取决于系统负载。

多表连接、聚合函数、UNION等视图不能直接更新。
时间:操作直接失败。
位置:数据库内。
具体数字:无具体数字。

视图中的NULL值或计算列可以阻止更新。
时间:操作直接失败。
位置:数据库内。
具体数字:无具体数字。

对基表的直接更改会同步影响所有从属视图。
时间:立即生效。
位置:数据库内。
具体数字:无具体数字。

设计视图必须考虑可升级性限制。
老实说:不要使用复杂的视图直接修改数据。

mysql如何实现多表关联查询

JOIN分为内连接、左连接和右连接。
内部连接检查匹配。
左连接检查所​​有左表,如果右表没有匹配则返回 NULL。
右连接检查整个右表,如果左表没有匹配则返回NULL。
MySQL 不支持完全外部联接。
使用 UNION 连接左连接和右连接。

使用Chain JOIN连接多个表,并把ON条件写清楚。
例如,要检查用户订购的产品,请使用 INNER JOIN。

外键索引提高了性能,ALTERTABLE 添加了索引。
使用 WHERE 过滤数据,无需扫描整个表。
没有ON条件不要使用JOIN,否则会爆炸。
选择 JOIN 类型检查交易,选择 INNER 类型检查交集。

自己掂量一下。