MySQL中三表子查询的用法和实现方式mysql三表子查询

几天前,我帮助一位朋友完成了一个翻新旧木制家具的项目。
那天休息,我们彻底打磨了家具表面,然后涂了一层清漆。
当我刷漆时,我注意到旧柜子上的把手有点松。
我试图用锤子和钉子来固定它,但是当我把它钉进去时,钉子无法进入,一块木头从手柄上掉了下来。
这次我突然想到这个脚本有点类似于针对数据库中三个表的子查询。

在数据库中,有时您会遇到需要从三个不同表中过滤数据的情况,例如需要从不同部分修复这个松散的句柄。
例如,我朋友的衣柜由三部分组成:木头、钉子和锤子。
在数据库中,三张表就像木材、钉子和锤子,三表子查询就是解决句柄问题的方法。

你看,我打磨家具的时候,就像设置查询条件,用子查询作为一颗钉子,固定数据之间的关系。
虽然最终效果不错,但过程中的小故障和处理复杂的 SQL 查询时一样,需要小心,不要选错钉子,导致数据掉出来。

那么,如果我遇到针对数据库中三个表的子查询问题,我该如何解决呢?例如,我需要查询某个班级成绩最高的学生及其成绩,并按照成绩降序排序。
然后我一步一步构建查询,就像调整衣柜的把手一样,确保每个关联都像钉子一样精确。

等等,还有别的事。
我突然想到,如果三表子查询再复杂一点的话,就会像那个柜子一样,需要更复杂的工艺和工具。
那么,有没有什么技巧可以让我们更轻松的处理复杂的三表子查询呢?

MySQL 子查询中 any_value 和 WHERE IN 失效的原因是什么?

显然,在MySQL中,在子查询中使用ANY_VALUE和WHEREIN的问题实际上由于函数的特点和语法规则而变得复杂。
我们先来说说最重要的事情。
ANY_VALUE() 函数用于为组查询中的行随机选择指定的列值,但不保证唯一性。
这导致 WHEREIN 条件可能匹配整个表的所有行。
比如我们去年跑的一个项目,大概有3 000级左右的数据就出现了这样的问题。

我最初以为只要在子查询中使用 ANY_VALUE() 就可以从每个组中随机选择 ids,但是我发现这是错误的,因为当 type group 之后的 ANY_VALUE(id) 返回重复的 ids 或非目标值时,WHEREIN 可能会匹配所有行。
后来我发现有一个细节非常关键,就是使用确定性的聚合函数,比如MIN或者MAX,来保证值的唯一性。

另一件事是,未命名的结果列子查询也是一个很大的陷阱。
例如,如果结果列没有通过AS显式命名,MySQL将自动生成列名。
目前,外部查询可能无法正确引用列、导致语法解析失败或返回整个表。
例如,如果我们在子查询中不使用 AS 命名结果列,则外部查询的 idIN(...) 可能与子查询的隐式列名不匹配。

等一下,还有一件事是始终为子查询结果列指定别名,以避免MySQL自动生成列名引起的歧义。
我认为值得一试。

调试建议,如果结果不正常,请先单独执行子查询,检查返回值是否符合WHEREIN期望。
通过上面的调整,可以保证子查询和WHEREIN协同工作,返回预期的结果。