为何查询Perryridge所有支行有账户的客户需用指定NOT EXISTS EXCEPT SQL?
为啥第一段SQL对,第二段错?
先明确需求
我们要找的是Perryridge地区每一家支行都有账户的客户——说白了就是,这个地区有N家支行,客户得在这N家都开了账户,一个都不能落。
先搞懂EXCEPT的意思
A EXCEPT B就是取「在A里但不在B里」的记录,如果结果是空的,说明A的所有内容都包含在B里。
第一段SQL的逻辑(正确)
SELECT DISTINCT S.customer_name FROM depositor S WHERE NOT EXISTS ((SELECT branch_name FROM branch WHERE branch_city = 'Perryridge') EXCEPT (SELECT branch_name FROM depositor D, account A WHERE D.account_number = A.account_number AND D.customer_name = S.customer_name))
这里的子查询是「Perryridge地区所有支行」减去「当前客户有账户的支行」,NOT EXISTS表示这个差集是空的。
人话翻译:Perryridge的每一家支行,这个客户都有账户——正好命中我们的需求。
第二段SQL的逻辑(错误)
SELECT DISTINCT S.customer_name FROM depositor S WHERE NOT EXISTS ((SELECT branch_name FROM depositor D, account A WHERE D.account_number = A.account_number AND D.customer_name = S.customer_name) EXCEPT (SELECT branch_name FROM branch WHERE branch_city = 'Perryridge'))
这里的子查询是「当前客户有账户的支行」减去「Perryridge地区的支行」,NOT EXISTS表示这个差集是空的。
人话翻译:这个客户的所有账户都开在Perryridge的支行里,但完全没要求覆盖该地区所有支行——比如客户只在Perryridge的1家支行有账户,也会被这段SQL选出来,这显然不是我们要的结果。
提个笔误
你给出的两段SQL里,关联条件写的是D.customer_name = A.customer_name,这明显有误——account表不存在customer_name字段,应该改成D.customer_name = S.customer_name,不然没法关联到外层的当前客户,逻辑直接失效。
内容的提问来源于stack exchange,提问作者work
相关产品推荐
相关产品推荐

