为何下述SQL查询语句会返回错误?请详细解释原因
为啥你的SQL查询会报错?
嘿,我来帮你理清楚这个SQL语句出问题的地方~
你的查询语句是:
SELECT date, quantity, hardwareID FROM orders WHERE hardwareID = SELECT hardwareID FROM hardware_parts WHERE description LIKE '%DRIVE%';
核心问题:子查询返回多行,=运算符接不住
当你运行里面的子查询SELECT hardwareID FROM hardware_parts WHERE description LIKE '%DRIVE%'时,如果有多个硬件部件的描述里包含"DRIVE",它会返回好几个hardwareID值。但外层的WHERE hardwareID = [子查询]用的是=,这个运算符只能用来匹配单个值——数据库面对一堆值,根本不知道该拿哪一个去和orders表的hardwareID做比较,直接就会抛出类似“子查询返回多于一行”的错误。
另外还有个小语法问题:你的子查询没有加括号,有些数据库会因为这个直接判定语法错误,这也是需要修正的点。
怎么修复?给你两种常用方案
方案一:用
IN代替=(最常用,适合子查询返回多行的情况)IN运算符就是专门用来匹配多个值的,把=换成IN,同时给子查询加上括号:SELECT date, quantity, hardwareID FROM orders WHERE hardwareID IN (SELECT hardwareID FROM hardware_parts WHERE description LIKE '%DRIVE%');方案二:确保子查询只返回一行(如果业务允许)
如果你确定匹配"%DRIVE%"的硬件只有一个,或者只需要其中一个结果,可以给子查询加个限制条件让它只返回一行,比如用LIMIT 1(MySQL/PostgreSQL适用,SQL Server用TOP 1,Oracle用ROWNUM <=1):SELECT date, quantity, hardwareID FROM orders WHERE hardwareID = (SELECT hardwareID FROM hardware_parts WHERE description LIKE '%DRIVE%' LIMIT 1);
额外小提示:还有两种情况要注意
- 子查询返回空结果:如果子查询没找到任何匹配的
hardwareID,用=的话会变成hardwareID = NULL,SQL里NULL和任何值比较都是UNKNOWN,最后返回0行;而用IN的话也是返回0行,但逻辑更清晰。 - 性能优化:如果你的表数据量很大,子查询的性能可能不如JOIN。可以改成JOIN的写法,逻辑一样,但有时候执行效率更高:
SELECT o.date, o.quantity, o.hardwareID FROM orders o JOIN hardware_parts hp ON o.hardwareID = hp.hardwareID WHERE hp.description LIKE '%DRIVE%';
内容的提问来源于stack exchange,提问作者Haruto Rika
相关产品推荐
相关产品推荐

