SQL两表关联筛选大于第二表字段均值的行结果异常问题
现有SQL的核心问题
你的写法存在3个关键错误,直接导致返回结果不符合预期:
- 外层查询直接写了聚合函数
AVG(actor_age)但没有写GROUP BY分组条件,绝大多数SQL引擎会将查询结果强制聚合成单行返回,这就是你最终只拿到1条记录的核心原因。 - 关联逻辑错误:用
actors.id = oscar_winners.id做关联条件不符合表结构设计逻辑——oscar_winners表作为存储获奖记录的表,和actors关联应该用表内存储的演员外键字段(通常命名为actor_id)和actors表的主键id匹配,直接关联两张表的id字段会导致大量记录匹配错误、甚至关联失败。 - 计算平均年龄的子查询缺少
FROM actors声明,会导致计算的平均值不是actors全表的actor_age均值,而是外层关联后临时结果集的均值,计算基准错误,筛选条件自然不准。
正确实现代码
你的需求本质是:拿oscar_winners表的每一条记录的winner_age,和actors全表的actor_age平均值做比较,筛选出大于平均值的记录。不需要在外层做聚合,正确写法如下:
SELECT ow.winner_age, avg_actor.total_avg_age AS all_actor_average_age FROM oscar_winners ow -- 如果需要关联查询演员的其他信息就保留该JOIN,仅判断年龄的话可以省略 INNER JOIN actors a ON a.id = ow.actor_id -- 请将ow.actor_id替换为你表中实际存储的演员关联外键字段名 CROSS JOIN ( -- 单独计算actors全表的平均年龄,作为常量值关联,不会改变原结果集的行数 SELECT AVG(actor_age) AS total_avg_age FROM actors ) avg_actor WHERE ow.winner_age > avg_actor.total_avg_age;
如果不需要关联取演员表的其他字段,可以写得更简洁:
SELECT winner_age, (SELECT AVG(actor_age) FROM actors) AS all_actor_average_age FROM oscar_winners WHERE winner_age > (SELECT AVG(actor_age) FROM actors);
这个写法里的平均年龄计算是完全独立的子查询,不会受外层查询逻辑干扰,能正确返回所有符合条件的记录。
内容的提问来源于stack exchange,提问作者Raitiko
相关产品推荐
相关产品推荐

