這是MYSQL的語法。
先來個情境吧。
A表
download_id
data1
data2
B表
id
data1
data2
SQL 語法
DELETE FROM `A` WHERE download_id IN (SELECT download_id FROM B WHERE data1 = 6)
認真來這邊其實有先看出一個問題。就是B表其實是沒有 download_id 的。
就我個人的看法。理論上是會報錯才對。
但是實際情況是。
它將A表的資料全刪了。
我有試著用同樣的條件在phpmyadmin
確實會符合全刪A表。
其實這我不太理解。正常單純去執行
SELECT download_id FROM B WHERE data1 = 6
它是會報錯說找不到 download_id
但整段放進去執行。居然會IN到全部。而造成A表的資料全數刪除。
想說,有無高手可以幫我解惑這個問題到底是什麼。
補充說明:
這是一個SQL語法的討論。原則上我清楚這種寫法很危險。
這是從一個舊專案看到的語法。並不是我寫的。
只是發現到這樣有點奇怪的情況,才想拿出來討論看看。
單純討論,不是要找解決方式。
那個SQL應該判斷是A表的欄位~所以才沒有報錯~
你可以試試..
DELETE FROM `A` WHERE download_id IN (SELECT A.download_id FROM B WHERE data1 = 6)
這樣應該也是正常執行~
所以他會全部刪除~很正常...A比對A的欄位...一定符合@@"
嗯,這個倒是覺得有可能是這樣。後面的download_id其實是依A表。
我試試改成 B.download_id 看還會不會全刪除好了。
試完了我再回報看看。
OK!
總算了解原理了。
確實如你所說的,IN裏面的 download_id 的確是視為A表的download_id
所以 A=A。就全刪除了。
我使用了 B.download_id 果然就報錯了。
另外我也有追加一個測試。
也就是如果我將B表也增加了一個 download_id 欄位的話。
那IN內的 download_id 就會將其視為B表。不會再用A表了。
總算是解開我的疑問了。
你給了我想要追求的答案。就給你最佳解了。
用IN做查詢時因B表沒有download_id,導致子查詢回傳"NULL",故直接執行了A表的刪除,你可以嘗試使用EXISTS回傳,因為EXISTS會判斷整條指令是否準確匹配
目前我也在想是NULL的問題,導致WHERE條件消失。
但也覺得這樣很可怕就是了。
CSDN看到這個內容:n,exists其实是两个功能差不多的sql命令,如果查询的两个表大小相当,用in和exists差别不大。
in查询相当于多个or条件的叠加,这个相信大家都比较容易理解
exists则主要用于主表的结果集小,也就是外层循环少的情况,而in是用于子查询的结果集少的情况。
exists查询时对主表(外表)用loop逐条循环查询,每次查询都会判断exists的条件语句,当 exists里的条件语句能够返回记录行时(注:无论记录行是多少,只要能返回),条件就为真,则外循环LOOP返回当前loop到的这条记录,反之如果exists里的条 件语句不能返回记录行,则当前loop到的这条记录被丢弃,exists的条件就像一个bool条件,当能返回结果集则为true,不能返回结果集则为 false.
原文链接:https://blog.csdn.net/wh445306/article/details/107024029
爬一下文看來IN 沒有true false的概念,只要有匹配到結果及為真
其實這目前也是我納悶的點。
理論上後面因該是匹配不到資料,也不太可能為真。那就不該能IN到條件。
不過「純真的人」給了另一個思維出來。搞不好可能實際情況是他說的。
經實驗証明,並不太偏向你說的。
而是偏向「純真的人」說的情況。
我多方測試後也了解為何會這樣了。
不過還是感謝與我討論。
確實如他所說,還是很好奇它的原理
若B表查詢有資料~會刪除~
但B表無資料~不會刪除~
MSSQL為例
declare @AA table(
idx int
)
declare @BB table(
idc int
)
insert into @AA
values(1)
,(2)
insert into @BB
values(3)
,(4)
不會刪除A表~~
delete from @AA
where idx in(
select idx
from @BB b
where idc = 2
)
select *
from @AA
會刪除A表~~
delete from @AA
where idx in(
select idx
from @BB b
where idc = 3
)
select *
from @AA
所以MS SQL 較正常, MySQL 則有些疑問。
要不要改用MS SQL 試看看