题目
获取至少提供S2提供的所有零件的供应商的编号,表sp如下所示。
分析
EXISTS / IN:查询有结果则返回true,查询为空则返回false。
NOT EXISTS / NOT IN:查询有结果返回false,查询为空返回true。
EXISTS与IN不同处在于:a EXISTS b是指a中存在b,即a包含b;而a IN b是指a在b中,即b包含a。
Exists首先执行外层查询,再执行内层查询,而IN相反。
EXISTS
EXISTS
用于检查子查询是否返回结果。如果子查询返回至少一个行,EXISTS
返回 TRUE
;否则返回 FALSE
。
通常,EXISTS
用于筛选主查询中存在相关行的数据。它表示 "至少存在一个满足条件的行"。
EXISTS
常用于子查询,通常与主查询之间的关系有关,以检查是否满足特定条件。
示例
SELECT employee_name
FROM employees
WHERE EXISTS (
SELECT 1
FROM departments
WHERE departments.department_id = employees.department_id
);
在这个查询中,EXISTS
用于检查是否至少存在一个与员工的部门相关联的部门。
NOT EXISTS
NOT EXISTS
与 EXISTS
相反,它用于检查子查询是否不返回结果。如果子查询不返回任何行,NOT EXISTS
返回 TRUE
;否则返回 FALSE
。
NOT EXISTS
常用于筛选主查询中不存在相关行的数据。它表示 "不存在满足条件的行"。
通常,NOT EXISTS
用于查找主查询中没有匹配的行。
示例
SELECT customer_name
FROM customers
WHERE NOT EXISTS (
SELECT 1
FROM orders
WHERE orders.customer_id = customers.customer_id
);
在这个查询中,EXISTS
用于检查是否至少存在一个与员工的部门相关联的部门。
注意:在 EXISTS和NOT EXISTS
子查询中,SELECT
语句通常不返回具体的列值,而只关心是否存在满足条件的行,即判断true或false。
IN
IN
用于检查一个列的值是否在指定的值列表中。如果列的值与值列表中的任何一个值匹配,IN
返回 TRUE
;否则返回 FALSE
。
IN
通常用于筛选主查询中具有特定属性的数据。它表示 "值匹配值列表中的任何一个"。
示例
SELECT product_name
FROM products
WHERE category_id IN (1, 2, 3);
在这个查询中,IN
用于查找那些属于指定类别的产品。
NOT IN
NOT IN
与 IN
相反,它用于检查一个列的值是否不在指定的值列表中。如果列的值与值列表中的任何一个值都不匹配,NOT IN
返回 TRUE
;否则返回 FALSE
。
NOT IN
通常用于筛选主查询中不具有特定属性的数据。它表示 "值不匹配值列表中的任何一个"。
示例
SELECT user_name
FROM users
WHERE user_id NOT IN (5, 7, 9);
在这个查询中,NOT IN
用于查找那些用户不在指定的用户列表中的用户。
sql语句
SELECT DISTINCT S.SNO AS 供应商编号
FROM SP S
WHERE NOT EXISTS (
SELECT PNO
FROM SP P
WHERE P.SNO = 'S2' AND P.PNO NOT IN (
SELECT PNO
FROM SP Q
WHERE Q.SNO = S.SNO
))
AND S.SNO NOT IN('S2');
总体来讲,就是判断当前供应商所供应的零件集合是否包含s2所供应的零件的集合。接下来分段进行分析。
此处相当于获取当前供应商所供应的零件集合,后面以T1表示。
此处相当于判断是否存在SNO的值为S2,且PNO不在集合T1中的数据,若有则返回true,否则返回false。
换而言之,就是在判断S2的零件集合是否完全被集合T1包含。
显然若集合T1包含S2的零件集合的话,集合T1的补集是不会和S2的零件集合有交集的,即会返回false。
然后经过第三行的NOT EXISTS后就成了true。(总感觉有种双重否定变肯定的感觉?)
这一行是为了在结果中排出S2,因为S2的零件集合一定是包含它本身的,因而会在结果中。
看一下结果吧~ 总算绕明白了(倒.jpg)
(by 归忆)