亚洲一区精品自拍_2021年国内精品久久_男同十八禁gv在线观看_免费观看a级性爱黄片

當(dāng)前位置:文章中心>技術(shù)教程
公告通知 新聞快遞 技術(shù)教程 產(chǎn)品展示

SQL查詢:慎用 IN 和 NOT IN

發(fā)布時間:2022-02-14 點(diǎn)擊數(shù):944

今天忽然想到之前在書上看到的一個比如,竟然想不起來了.

所以翻書找出來,測驗(yàn)一下.

-- drop table father,son
create table father(fid int,name varchar(10),oid int)
create table son(sid int,name varchar(10),fid int)


insert into father(fid,name,oid)
values(1,'father',5),(2,'father',9),(3,'father',null),(4,'father',0)

insert into son(sid,name,fid)
values(1,'son',2),(2,'son',2),(3,'son',3),(4,'son',null),(5,'son',null)

select * from father
select * from son

image.png

in和exists差異開端測驗(yàn)吧,現(xiàn)在測驗(yàn)運(yùn)用in、not in 或許帶來的“過錯”。之所以過錯,是由于咱們總是以自然語言去了解SQL,卻忽略了數(shù)學(xué)中的邏輯語法。不廢話了,測驗(yàn)看看吧!

【測驗(yàn)一:in子查詢】

--回來在son中存在的一切father的數(shù)據(jù)

--正確的寫法:
select * from father where fid in(select fid from son)

--過錯的寫法:
select * from father where fid in(select oid from son)

image.png

闡明:

兩個查詢都履行沒有犯錯,可是第二個tsql的子查詢寫錯了。子查詢(select oid from son)實(shí)踐單獨(dú)履行會犯錯,由于表son不存在字段oid,可是在這里體系不會提示過錯。而且father表有4行數(shù)據(jù),一切子查詢掃描了4次son表,可是第二個查詢中,實(shí)踐也只掃描了1次son表,也便是son表沒有用到。

即便這樣寫也 不會犯錯:select*fromfatherwherefidin(selectoid)

這個查詢的意思是,表father中每行的fid與oid比較,相同則回來值。

實(shí)踐查詢是這樣的:select * from father where fid = oid

測驗(yàn)一中,fid in(select fid from son)子查詢中包含null值,所以 fid  in(null)回來的是一個未知值??墒窃谒⑦x器中,false和unknown的處理方式類似。因而榜首個子查詢回來了正確的成果集。

image.png

【測驗(yàn)二:not  in子查詢】

--回來在son中不存在的一切father的數(shù)據(jù)

--過錯的寫法:
select * from father where fid not in(select fid from son)

--過錯的寫法:
select * from father where fid not in(select oid from son)

--正確的寫法:
select * from father where fid not in(select fid from son where fid is not null)

image.png

闡明:

查看select fid from son,子查詢中有空值null,子查詢中的值為(2,3,null),謂詞fid in(2,3,null)永遠(yuǎn)不會回來false,只反會true或unknown,所以謂詞fidnot in(2,3,null)只回來not true 或not unknown,成果都不會是true。所以當(dāng)子查詢存在null時,not in和not exists 在邏輯上是不等價的。

總結(jié)

In 或 not in在SQL語句中經(jīng)常用到,尤其當(dāng)子查詢中有空值的時候,要慎重考慮。由于即便寫了“正確”的腳本,可是回來成果卻不正確,也不犯錯。

在不是很了解的情況下,最好運(yùn)用 exists和 not exists來替換。而且exists查詢更快一些,由于只要在子查詢找到榜首個契合的值就不繼續(xù)往下找了,所以能用exists就用吧。