子查询执行报错但手动输入ID正常,求SQL语法问题排查建议
解决SQL语法错误并获取评价数量最多的学生
首先咱们先搞定你遇到的语法错误问题,然后再解决核心需求——找到两类评价中数量最多的学生。
语法错误的根源
你原来的查询里,子查询的结尾分号和括号位置错了,而且IN子查询里加ORDER BY是完全没必要的(数据库处理IN的时候不会关心子查询结果的顺序)。看你这段代码:
SELECT first_name,last_name FROM People WHERE ID IN ( SELECT ID_Student FROM Evaluations WHERE category IN ( 'Exam', 'Behaviour') GROUP BY ID_Student ORDER BY count(ID_Student) DESC ; -- 这里的分号不该放在这儿 );
子查询内部的分号会提前终止子查询,导致后面的);变成无效语法,直接引发报错。
先修正语法(但还没满足核心需求)
如果只是想让查询能跑起来,去掉子查询里的ORDER BY,并把分号移到整个语句末尾:
SELECT first_name, last_name FROM People WHERE ID IN ( SELECT ID_Student FROM Evaluations WHERE category IN ('Exam', 'Behaviour') GROUP BY ID_Student );
不过这个查询只是返回所有在Exam和Behaviour中有评价的学生,还没筛选出评价数量最多的那些。
满足核心需求:获取评价数量最多的学生
要拿到数量最多的学生(包括并列第一的情况),有两种常用方法:
方法1:先计算最大评价数,再匹配学生
这种方法兼容性好,几乎所有数据库都支持:
SELECT p.first_name, p.last_name FROM People p JOIN ( -- 先算出每个学生的两类评价总数 SELECT ID_Student, COUNT(*) AS total_evals FROM Evaluations WHERE category IN ('Exam', 'Behaviour') GROUP BY ID_Student ) student_evals ON p.ID = student_evals.ID_Student -- 筛选出总数等于最大评价数的学生 WHERE student_evals.total_evals = ( SELECT MAX(total) FROM ( SELECT COUNT(*) AS total FROM Evaluations WHERE category IN ('Exam', 'Behaviour') GROUP BY ID_Student ) temp_counts );
方法2:用窗口函数(更简洁,适合支持窗口函数的数据库)
如果你的数据库是MySQL 8+、PostgreSQL、SQL Server等,用窗口函数RANK()可以更直观地实现:
SELECT first_name, last_name FROM ( SELECT p.first_name, p.last_name, -- 按评价数降序排名,并列第一的学生rank都是1 RANK() OVER (ORDER BY COUNT(e.ID_Student) DESC) AS eval_rank FROM People p JOIN Evaluations e ON p.ID = e.ID_Student WHERE e.category IN ('Exam', 'Behaviour') GROUP BY p.ID, p.first_name, p.last_name ) ranked_students WHERE eval_rank = 1;
为什么你手动输入ID能运行?
因为手动输入ID的IN列表是纯值列表,语法结构完全正确,没有子查询里的语法错误问题,所以能正常执行。
内容的提问来源于stack exchange,提问作者Matias Barrios
相关产品推荐
相关产品推荐

