CREATE TABLE `A` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=latin1 CREATE TABLE `B` ( `id` int(11) NOT NULL AUTO_INCREMENT, `AID` int(11) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=latin1
SELECT ID,NAME FROM A WHERE EXISTS (SELECT 1 FROM B WHERE A.ID=B.AID) ;
結果為:
表A和表B是1對多的關系 A.ID => B.AID
SELECT ID,NAME FROM A WHERE EXIST (SELECT * FROM B WHERE A.ID=B.AID)
執行結果為
1 A1
2 A2
原因可以按照如下分析
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=1)
---> SELECT * FROM B WHERE B.AID=1有值,返回真,所以有數據
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=2)
---> SELECT * FROM B WHERE B.AID=2有值,返回真,所以有數據
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=3)
---> SELECT * FROM B WHERE B.AID=3無值,返回假,所以沒有數據
NOT EXISTS 就是反過來
SELECT ID,NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID=B.AID)
執行結果為
3 A3
===========================================================================
EXISTS = IN,意思相同不過語法上有點點區別,好像使用IN效率要差點,應該是不會執行索引的原因
SELECT ID,NAME FROM A WHERE ID IN (SELECT AID FROM B)
NOT EXISTS = NOT IN ,意思相同不過語法上有點點區別
SELECT ID,NAME FROM A WHERE ID NOT IN (SELECT AID FROM B)
===========================================================================
EXISTS:
系統要求進行SQL優化,對效率比較低的SQL進行優化,使其運行效率更高,其中要求對SQL中的部分in/not in修改為exists/not exists
修改方法如下:
in的SQL語句
SELECT id, category_id, htmlfile, title, convert(varchar(20),begintime,112) as pubtime
FROM tab_oa_pub WHERE is_check=1 and
category_id in (select id from tab_oa_pub_cate where no='1')
order by begintime desc
修改為exists的SQL語句
SELECT id, category_id, htmlfile, title, convert(varchar(20),begintime,112) as pubtime
FROM tab_oa_pub WHERE is_check=1 and
exists (select id from tab_oa_pub_cate where tab_oa_pub.category_id=convert(int,no) and no='1')
order by begintime desc
exists表示()內子查詢語句返回結果不為空說明where條件成立就會執行主sql語句,如果為空就表示where條件不成立,sql語句就不會執行。
not exists和exists相反,子查詢語句結果為空,則表示where條件成立,執行sql語句。負責不執行。
select nvl(count(distinct o.member_id), 0) as newMembers from order_info o, member mb where o.member_id = mb.member_id and o.is_delete = 'N' and mb.is_delete = 'N' and not exists (select oi.member_id from order_info oi, member mb where oi.is_delete = 'N' /*有效訂單條件*/ and (oi.audit_time is not null and oi.order_state NOT in (18, 19, 25)) and oi.member_id = mb.member_id)
select oi.member_id
from order_info oi, member mb
where oi.is_delete = 'N'
/*有效訂單條件*/
and (oi.audit_time is not null and
oi.order_state NOT in (18, 19, 25))
and oi.member_id = mb.member_id
這條sql是有數據的,所以not exists 在執行的時候,是沒數據的,exists是有數據的
https://www.iteye.com/blog/yangzhonglei-699673