本文主要是介绍认知幻像:如果有这样一道面试题,可以如何作答?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
书接上回,虽然我们知道,SQL有着强大的标准体系,但是在实践中,不同数据库却有不同的实现方式。
除此之外,有时候用常规的思维逻辑而不是计算逻辑去推理SQL执行方式,也有可能出现不同于现实的判定。
以下这个问题,也是来自“云和恩墨大讲堂”朋友提出的。
最后这个查询,在 enmotest 表中,根本不存在 name 字段,查询的结果会是怎样呢?
大家想象一下,如果这是一道面试题,你如何判断结果,如何解释背后的逻辑?
create table enmotech (id number,name varchar2(20));
insert into enmotech values(1,'Eygle');
create table enmotest (id number);
insert into enmotest values(1);
select * from enmotech where name in (select name from enmotest);
思考一分钟。
插播:2023 数据技术嘉年华大会,将会在4.7 ~ 4.8 北京开幕,大会特设数据迁移专场,欢迎接受我的赠票邀请(扫码),共享数据库技术盛会,免费报名链接:
https://modb.pro/event/804/395289
继续采用墨天轮的 SQLRUN 环境:
https://www.modb.pro/sqlrun/mysql
在Oracle数据库的执行结果如下:
在 云和恩墨 的 MogDB 执行结果如下:
网友提出的问题是:明明在 enmotest 表中不存在 name 字段,为什么不抛出不存在的异常,反而反回了外表的记录?
我们针对Oracle的查询,执行一个 10053 的跟踪事件(获得SQL解析过程),执行步骤如下:
SQL> alter session set events '10053 trace name context forever,level 1';
Session altered.
SQL> select * from enmotech where name in (select name from enmotest);
在跟踪文件中,可以清晰地看到执行计划的解析过程。以下解析步骤,说明了结果产生的原因。
对于子查询来说,父查询的所有字典信息可见,所以解析转换中,子查询的 NAME 自然就被解析为 ENMOTECH.NAME ,这样比较结果恒为真,就返还了父查询中所有的记录(此时如果父查询表中也不存在这个字段则会抛出异常):
SELECT "ENMOTECH"."ID" "ID","ENMOTECH"."NAME" "NAME" FROM "MOGDB"."ENMOTECH" "ENMOTECH" WHERE "ENMOTECH"."NAME"=ANY (SELECT "ENMOTECH"."NAME" "NAME" FROM "MOGDB"."ENMOTEST" "ENMOTEST")
Objects referenced in the statement
ENMOTECH[ENMOTECH] 76095, type = 1
ENMOTEST[ENMOTEST] 76096, type = 1
Objects in the hash table
Hash table Object 76095, type = 1, ownerid = 3808176908773422935:
No Dynamic Sampling Directives for the object
Hash table Object 76096, type = 1, ownerid = 14982774484177512411:
No Dynamic Sampling Directives for the object
这个题目的真正警示在于,如果开发人员凑巧写错了条件,而这个SQL的执行不会出现异常,只是结果不符合预期,我们需要提前识别这个误操作。
云和恩墨大讲堂 | 一个分享交流的地方
长按,识别二维码,加入万人交流社群
请备注:云和恩墨大讲堂
点个“在看”
你的喜欢会被看到❤
这篇关于认知幻像:如果有这样一道面试题,可以如何作答?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!