据我所知,当子查询包含至少一行时,EXISTS返回true,而如果子查询没有返回任何内容,则NOT EXIST返回true。所以对于给定的子查询,两者中的任何一个都应该返回true,对吧? 例如: 1)这将返回一个或多个城市中存在哪种商店?
SELECT DISTINCT store_type FROM stores
WHERE EXISTS
(SELECT *
FROM cities_stores
WHERE cities_stores.store_type = stores.store_type);
2)这会回归到哪个商店没有城市?
SELECT DISTINCT store_type FROM stores
WHERE NOT EXISTS
(SELECT *
FROM cities_stores
WHERE cities_stores.store_type = stores.store_type);
那么同一个子查询如何为这两个查询提供输出?一个使用EXIST而另一个使用NOT EXIST?
我从中得到了例子 http://dev.mysql.com/doc/refman/5.1/en/exists-and-not-exists-subqueries.html
另外,2 NOT NOT EXISTS如何帮助?这不是一种OR吗? 3)这会返回所有城市中存在哪种商店?
SELECT DISTINCT store_type FROM stores s1
WHERE NOT EXISTS (
SELECT * FROM cities
WHERE NOT EXISTS (
SELECT * FROM cities_stores
WHERE cities_stores.city = cities.city
AND cities_stores.store_type = stores.store_type));
答案 0 :(得分:3)
EXISTS()
子句的典型用法是检查相关表中给定行存在的相关行的位置:
CREATE TABLE clients
( client_id INTEGER NOT NULL PRIMARY KEY
, client_name varchar
);
CREATE TABLE products
( product_id INTEGER NOT NULL PRIMARY KEY
, product_name varchar
);
CREATE TABLE orders
( client_id INTEGER NOT NULL REFERENCES clients(client_id)
, product_id INTEGER NOT NULL REFERENCES products(product_id)
, quantity INTEGER NOT NULL DEFAULT 1
, order_date DATE
, PRIMARY KEY (client_id,product_id)
);
INSERT INTO clients(client_id, client_name) VALUES (1, 'Alice' ), (2, 'Bob' ), (3, 'Charly' ), (4, 'Diana' );
INSERT INTO products(product_id, product_name) VALUES (1, 'Apple' ), (2, 'Banana' ), (3, 'Citrus' );
INSERT INTO orders(client_id,product_id,order_date) VALUES (1,2, '2013-9-8'),(2,1, '2013-9-11'),(3,2, '2013-10-1');
-- Find clients who ordered something
SELECT * FROM clients cl
WHERE EXISTS (
SELECT * FROM orders oo
WHERE oo.client_id = cl.client_id
)
;
-- Find clients who never ordered anything
SELECT * FROM clients cl
WHERE NOT EXISTS (
SELECT * FROM orders oo
WHERE oo.client_id = cl.client_id
)
;
-- Find products that were never ordered
SELECT * FROM products pr
WHERE NOT EXISTS (
SELECT * FROM orders oo
WHERE oo.product_id = pr.product_id
)
;
答案 1 :(得分:2)
为了增加这一点,在使用NOT EXISTS
时,通过确保以不会否定索引的方式检查列来帮助提高性能。我认为这适用于较大的数据集,但仍然很有用。 Jayachandran在这里解释得非常好:http://social.msdn.microsoft.com/Forums/sqlserver/en-US/582544fb-beda-46c0-befd-4b28b5c2cdee/select-not-exists-very-slow
答案 2 :(得分:1)
Where not exists
非常有用的一个例子是插入时。如果您希望根据某些条件阻止添加重复行,则使用此功能会很有帮助。
例如,在创建参考数据表时,我也会关闭IDENTITY_INSERT
以保持数据库之间的ID一致。插入新的参考数据时,我这样做:
INSERT INTO ref_table
(ID, ReferenceData)
SELECT 425, 'foo' where not exists (select 1 from ref_table where ID = 425) UNION ALL
SELECT 426, 'bar' where not exists (select 1 from ref_table where ID = 426) UNION ALL
...
SELECT 532, 'biz' where not exists (select 1 from ref_table where ID = 532)
当然我总是确保我的插入内容是一致的,但我添加了这个条款以便安全测量。
答案 3 :(得分:0)
首先,您需要在内部查询(连接)中具有匹配项的商店类型,在第二种情况下,您希望商店类型与内部查询不匹配!!!
当使用EXISTS / NOT EXISTS子句时,您总是加入内部和外部查询,然后您只需选择是否希望结果匹配或没有匹配。