为什么SQL子查询报错‘最多返回一条记录’而另一种写法正常?
报错的子查询存在的核心问题
你写的子查询有两个本质缺陷,直接触发多行返回报错:
- 标量子查询的运行规则是必须最多返回1行1列,但该子查询
(SELECT Building FROM Departments WHERE Building Like 'A#')没有任何关联限制、聚合逻辑或行数约束,只要Departments表中存在超过1个Building符合LIKE 'A#'的匹配规则,就会返回多行结果,直接触发At most one record can be returned by this subquery的报错。 - 你完全遗漏了子查询的判断逻辑:WHERE条件中在AND后面直接跟了一个包裹子查询的括号,没有说明子查询结果要和哪个字段做比较、做什么逻辑的匹配,SQL无法识别这个条件的判断规则。
可运行写法的实际逻辑
你后续能正常运行的写法,本质已经完全脱离了子查询的逻辑:
- 该写法将Departments表直接加入FROM子句,和Jobs、Workers的关联结果做无初始条件的交叉连接(笛卡尔积),之后在WHERE子句中用
Departments.Building Like 'A#'做行过滤。 - 之所以没有报多行错误,是因为此时Building字段是直接出现在主查询的WHERE判断中,不再是作为子查询的多值返回;同时你添加的全字段GROUP BY对关联产生的重复行做了去重,也适配了Access对非聚合查询的分组校验规则,所以查询能正常执行。
- 但该写法存在逻辑隐患:如果一个工作岗位关联的多个部门行都符合Building匹配规则,结果集依然会返回重复的人员记录,属于隐式交叉连接的副作用,并不是规范的表关联写法。
规范的实现参考
如果需求是筛选所属部门建筑以A开头、薪资高于15000的工作人员,应当使用显式JOIN关联Departments表,替代无逻辑的子查询:
SELECT W.FullName AS [Full Name], W.Phone, W.Address, W.Age, J.Salary, J.Job FROM Jobs J INNER JOIN Workers W ON J.JobID = W.JobID INNER JOIN Departments D ON D.DepartmentID = J.DepartmentID -- 此处替换为库中Jobs与Departments的实际关联外键 WHERE J.Salary > 15000 AND D.Building LIKE 'A#*' -- 若使用Access数据库,需匹配对应通配符规则筛选A开头后跟数字的建筑名 ORDER BY J.Salary
内容的提问来源于stack exchange,提问作者KLee
相关产品推荐
相关产品推荐

