1.情景展示
現在有一張表,需要將表中某字段的值不是以指定字符開頭的列進行刪除,如何實現?
2.問題分析
錯誤方案一:同事想到的是:這種方式
咱們來看一下,這個表總共有多少條數據
本來表數據總共才4萬多條數據,然而使用上面的查詢方式,卻查出了1多個億的數據,真不知道這數據庫是怎么想的。
錯誤方案二:既然不行,我首先想到的是:使用not like實現,實踐結果如下:
再來看一下,使用like查詢有多少條數據。
總共的數據為:40059+3972=44031條 數據,比總表數44295要少,也就是說:使用not like查詢會遺漏數據,具體什么原因想不通。
3.解決方案
正確方案一:not exists(),推薦使用
既然not like不行,我就想到用了使用exists()實現。
先來查查符合條件的,使用exists()查詢一下與使用like的語句是否一致。
結果一致,再看一下,使用not exists()的查詢結果
算一下,與總數是否一致:40323+3972=44295,與結果一致,大功告成!
--查詢表中不是以0.1.2.開頭的數據(使用exists實現) SELECT COUNT(1) FROM BASE_ORG_INFO T WHERE NOT EXISTS (SELECT 1 FROM (SELECT ORGID FROM BASE_ORG_INFO WHERE ORGSEQ LIKE '0.1.2.%') S WHERE S.ORGID = T.ORGID)
如何刪除這些數據?
--刪除表中某字段不是以0.1.2.開頭的數據(使用IN+EXISTS實現) DELETE FROM BASE_ORG_INFO T2 WHERE T2.ORGID IN (SELECT T.ORGID FROM BASE_ORG_INFO T WHERE NOT EXISTS (SELECT 1 FROM (SELECT ORGID FROM BASE_ORG_INFO WHERE ORGSEQ LIKE '0.1.2.%') S WHERE S.ORGID = T.ORGID))
執行結果:
方案二:not in()
DELETE FROM BASE_ORG_INFO T2 WHERE T2.ORGID IN (SELECT T.ORGID FROM BASE_ORG_INFO T WHERE T.ORGID NOT IN (SELECT ORGID FROM BASE_ORG_INFO WHERE ORGSEQ LIKE '0.1.2.%'))
執行結果如下:
20200617補充說明:
如文末評論區二樓所言,此時,SELECT ORGID FROM BASE_ORG_INFO WHERE ORGSEQ LIKE '0.1.2.%'),需要確保ORGID不能為空,否則可能會出現漏刪
(ORGID為空,ORGSEQ既有以0.1.2開頭的,也有不是以它開頭的,存在這種可能性)!
但反過來說,只要確保ORGID非空,使用NOT IN()就不存在漏洞。