SQL中NOT IN與NOT EXISTS不等價(jià)的問題
在對(duì)SQL語句進(jìn)行性能優(yōu)化時(shí),經(jīng)常用到一個(gè)技巧是將IN改寫成EXISTS,這是等價(jià)改寫,并沒有什么問題。問題在于,將NOT IN改寫成NOT EXISTS時(shí),結(jié)果未必一樣。
執(zhí)行環(huán)境:MySQL
一、舉例驗(yàn)證
例如,有如下一張表 rr 。要求:選擇4月2號(hào)的數(shù)據(jù),并且其type1是4月1號(hào)沒有的(從表看,就是4月2號(hào)C的那條)。
使用NOT IN ,單純按照這個(gè)條件去實(shí)現(xiàn)
select * from rr where create_date='2024-04-02' and type1 not in ( select type1 from rr where create_date='2024-04-01' ) ;
使用NOT EXISTS
select r1.* from rr as r1 where r1.create_date='2024-04-02' and not exists ( select r2.type1 from rr as r2 where r2.create_date='2024-04-01' and r1.type1=r2.type1 ) ;
主要原因是4月1號(hào)的數(shù)據(jù)中,存在type1為NULL的。如果該type1不是NULL,使用NOT IN就可以正確找出來結(jié)果了。
其中的原理涉及三值邏輯。
二、三值邏輯簡述
以下的式子都會(huì)被判為unknown
1、 = NULL
2、> NULL
3、< NULL
4、<> NULL
NULL = NULL
unknown,它是因關(guān)系數(shù)據(jù)庫采用了NULL而被引入的“第三個(gè)真值”。
(這里還有一點(diǎn)需要注意:真值unknown和作為NULL的一種UNKNOWN(未知)是不同的東西。前者是明確的布爾類型的真值,后者既不是值也不是變量。為了便于區(qū)分,前者采用粗體小寫字母unknown,后者用普通的大寫字母UNKNOWN表示。)
加上true和false,這三個(gè)真值之間有下面這樣的優(yōu)先級(jí)順序。
- AND 的情況:false > unknown > true
- OR 的情況:true > unknown > false
下面看具體例子,連同unknown一起理解下
三、附錄:用到的SQL
(運(yùn)行環(huán)境Mysql)
1、表 rr 的構(gòu)建
-- 使用了with語句 with rr as ( select '2024-04-01' as create_date,'A' as type1,001 as code1 union all select '2024-04-01' as create_date,'A' as type1,002 as code1 union all select '2024-04-01' as create_date,'A' as type1,002 as code1 union all select '2024-04-01' as create_date,'B' as type1,013 as code1 union all select '2024-04-01' as create_date,null as type1,013 as code1 union all select '2024-04-02' as create_date,'B' as type1,013 as code1 union all select '2024-04-02' as create_date,'C' as type1,109 as code1 union all select '2024-04-03' as create_date,'A' as type1,002 as code1 union all select '2024-04-04' as create_date,'A' as type1,002 as code1 )
2、 unknown的理解
set @a:=2, @b:=5, @c:= NULL ; select @a+@b as result1, case when (@b>@c) is true then 'true!' when (@b>@c) is false then 'false!' else 'unknown' end as result2, -- 與NULL比較 case when (@a<@b and @b>@c) is true then 'true!' when (@a<@b and @b>@c) is false then 'false!' else 'unknown' end as result3, -- and條件下 的優(yōu)先級(jí)展示 case when (@a<@b or @b>@c) is true then 'true!' when (@a<@b or @b>@c) is false then 'false!' else 'unknown' end as result4, -- or條件下 的優(yōu)先級(jí)展示 case when (not(@b<>@c)) is true then 'true!' when (not(@b<>@c)) is false then 'false!' else 'unknown' end as result5
到此這篇關(guān)于SQL中NOT IN與NOT EXISTS不等價(jià)的問題的文章就介紹到這了,更多相關(guān)SQL NOT IN與NOT EXISTS不等價(jià)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- sql語句優(yōu)化之用EXISTS替代IN、用NOT EXISTS替代NOT IN的語句
- MySQL: mysql is not running but lock exists 的解決方法
- mysql insert if not exists防止插入重復(fù)記錄的方法
- UCenter info: MySQL Query Error SQL:SELECT value FROM [Table]vars WHERE noteexists
- mysql not in、left join、IS NULL、NOT EXISTS 效率問題記錄
- sql not in 與not exists使用中的細(xì)微差別
- Mysql中in和exists的區(qū)別?&?not?in、not?exists、left?join的相互轉(zhuǎn)換問題
相關(guān)文章
親自教你使用?ChatGPT?編寫?SQL?JOIN?查詢示例
這篇文章主要介紹了使用ChatGPT編寫SQL?JOIN查詢,作為一種語言模型,ChatGPT 可以就如何構(gòu)建復(fù)雜的 SQL 查詢和 JOIN 提供指導(dǎo)和建議,但它不能直接訪問 SQL 數(shù)據(jù)庫,它可以幫助您了解語法、最佳實(shí)踐和有關(guān)如何構(gòu)建查詢以高效執(zhí)行的一般指導(dǎo),需要的朋友可以參考下2023-02-02SQL Server 數(shù)據(jù)庫分區(qū)分表(水平分表)詳細(xì)步驟
最近幾個(gè)擔(dān)心網(wǎng)站數(shù)據(jù)量大會(huì)影響sqlserver數(shù)據(jù)庫的性能,所以提前將數(shù)據(jù)庫分表處理好,下面是ExceptionalBoy同學(xué)分享的詳細(xì)方法,需要的朋友可以參考下2021-03-03SQL?Server使用SELECT?INTO實(shí)現(xiàn)表備份的代碼示例
在數(shù)據(jù)庫管理過程中,有時(shí)我們需要對(duì)表進(jìn)行備份,以防數(shù)據(jù)丟失或修改錯(cuò)誤,在?SQL?Server?中,可以使用?SELECT?INTO?語句將數(shù)據(jù)從一個(gè)表備份到另一個(gè)表,本文通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2025-01-01SQL?Server數(shù)據(jù)庫分離和附加數(shù)據(jù)庫的操作步驟
數(shù)據(jù)庫的附加是數(shù)據(jù)庫在數(shù)據(jù)庫文件中添加到數(shù)據(jù)庫當(dāng)中的操作,下面這篇文章主要給大家介紹了關(guān)于SQL?Server數(shù)據(jù)庫分離和附加數(shù)據(jù)庫的操作步驟,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10大容量csv快速內(nèi)導(dǎo)入sqlserver的解決方法(推薦)
最近遇到這樣的問題:導(dǎo)入csv 數(shù)據(jù),并對(duì)導(dǎo)入的數(shù)據(jù)增加一個(gè)新的列date datetime,下面通過本文給大家分享大容量csv快速內(nèi)導(dǎo)入sqlserver的解決方法,感興趣的朋友一起看看吧2017-07-07SQL Server中利用正則表達(dá)式替換字符串的方法
這篇文章主要介紹了SQL Server中利用正則表達(dá)式替換字符串的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03調(diào)整SQLServer2000運(yùn)行中數(shù)據(jù)庫結(jié)構(gòu)
這篇文章主要介紹了調(diào)整SQLServer2000運(yùn)行中數(shù)據(jù)庫結(jié)構(gòu),十分實(shí)用的一個(gè)功能,這里推薦給大家,有需要的小伙伴可以參考下。2015-04-04使用SQL語句實(shí)現(xiàn)查詢排序,順序和倒序
這篇文章主要介紹了使用SQL語句實(shí)現(xiàn)查詢排序、順序和倒序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05SQL語句中含有乘號(hào)報(bào)錯(cuò)的處理辦法
這篇文章主要介紹了SQL語句中含有乘號(hào)報(bào)錯(cuò)的處理辦法,需要的朋友可以參考下2014-08-08